[portal-commits] JBoss Portal SVN: r8976 - in branches/UIServer: core/src/main/org/jboss/portal/core/presentation/server and 32 other directories.

portal-commits at lists.jboss.org portal-commits at lists.jboss.org
Fri Nov 16 11:47:30 EST 2007


Author: sohil.shah at jboss.com
Date: 2007-11-16 11:47:30 -0500 (Fri, 16 Nov 2007)
New Revision: 8976

Added:
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/StreamResponse.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/AsyncPages.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/MyGWTPrototype.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PartialRefresh.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/Portal.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortalLayout.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortletService.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortletServiceAsync.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortletWindowPanel.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/layout/
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/layout/LayoutManager.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/protocol/
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/protocol/Page.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/protocol/Window.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/service/
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/service/PortalRPC.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/service/PortalRPCAsync.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/widget/
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/widget/PortletWindow.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/controller/
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/controller/UIController.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/entry/
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/entry/EntryPoint.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/entry/GWTClientFilter.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/ajax/entry/
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/ajax/entry/PortalEntryPoint.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/classic/entry/
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/classic/entry/PortalEntryPoint.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/entry/
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/entry/EntryPointImpl.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/test/ajax/PortletServiceImpl.java
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/AsyncPages.gwt.xml
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/MyGWT.gwt.xml
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/PartialRefresh.gwt.xml
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/Portal.gwt.xml
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/PortalLayout.gwt.xml
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/asyncPages.html
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/cmsPortlet.html
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/images/
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/images/ico_16_maximize.gif
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/images/ico_16_minimize.gif
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/images/ico_16_normal.gif
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/index.html
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/jspPortlet.html
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/layout.html
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/mygwt.html
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/partialRefresh.html
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/portal.css
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/portal/
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/portal/index.html
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/prototype.js
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/weatherPortlet.html
Removed:
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/ajax/service/
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/model/Portal.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/model/PortalObject.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/service/
   branches/UIServer/uiserver/src/main/org/jboss/portal/uiserver/
   branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/uiserver/
Modified:
   branches/UIServer/core/src/main/org/jboss/portal/core/presentation/model/ModelLoaderImpl.java
   branches/UIServer/core/src/main/org/jboss/portal/core/presentation/server/MainProcessor.java
   branches/UIServer/core/src/main/org/jboss/portal/core/theme/PageRendition.java
   branches/UIServer/uiserver/build.xml
   branches/UIServer/uiserver/gwt-dev-env/AsyncPages(uiserver).launch
   branches/UIServer/uiserver/gwt-dev-env/MyGWT(uiserver).launch
   branches/UIServer/uiserver/gwt-dev-env/PartialRefresh(uiserver).launch
   branches/UIServer/uiserver/gwt-dev-env/Portal(uiserver).launch
   branches/UIServer/uiserver/gwt-dev-env/PortalLayout(uiserver).launch
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/ErrorResponse.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/LinkActivation.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/RedirectResponse.java
   branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/server/ProcessorResponse.java
   branches/UIServer/uiserver/src/resources/portal-uiserver.sar/META-INF/jboss-service.xml
   branches/UIServer/uiserver/src/resources/portal-uiserver.war/WEB-INF/web.xml
   branches/UIServer/uiserver/src/resources/portal-uiserver.war/asyncPages.html
   branches/UIServer/uiserver/src/resources/portal-uiserver.war/layout.html
   branches/UIServer/uiserver/src/resources/portal-uiserver.war/partialRefresh.html
Log:
integration

Modified: branches/UIServer/core/src/main/org/jboss/portal/core/presentation/model/ModelLoaderImpl.java
===================================================================
--- branches/UIServer/core/src/main/org/jboss/portal/core/presentation/model/ModelLoaderImpl.java	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/core/src/main/org/jboss/portal/core/presentation/model/ModelLoaderImpl.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -90,6 +90,12 @@
          String token = st.nextToken();
          portalObject = portalObject.getChild(token);
       }
+      
+      if(portalObject == null)
+      {
+         //Object by this id was not found in the Portal
+         return null;
+      }
             
       //Type
       Class<? extends UIObject> type = this.getType(portalObject);

Modified: branches/UIServer/core/src/main/org/jboss/portal/core/presentation/server/MainProcessor.java
===================================================================
--- branches/UIServer/core/src/main/org/jboss/portal/core/presentation/server/MainProcessor.java	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/core/src/main/org/jboss/portal/core/presentation/server/MainProcessor.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -23,18 +23,10 @@
 package org.jboss.portal.core.presentation.server;
 
 import java.io.InputStream;
-import java.util.Map;
-import java.util.List;
-import java.util.Iterator;
-import java.util.ArrayList;
 
 import org.apache.log4j.Logger;
 
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.ServletOutputStream;
-
 import org.jboss.portal.common.util.MarkupInfo;
-import org.jboss.portal.common.io.IOTools;
 import org.jboss.portal.jems.as.system.AbstractJBossService;
 import org.jboss.portal.web.ServletContextDispatcher;
 import org.jboss.portal.server.RequestControllerDispatcher;
@@ -42,13 +34,16 @@
 import org.jboss.portal.server.RequestController;
 import org.jboss.portal.server.ServerInvocation;
 import org.jboss.portal.theme.page.PageResult;
-import org.jboss.portal.theme.page.WindowContext;
-import org.jboss.portal.theme.page.WindowResult;
 
+
 import org.jboss.portal.presentation.RequestContext;
 import org.jboss.portal.presentation.server.Processor;
 import org.jboss.portal.presentation.server.ProcessorRequest;
 import org.jboss.portal.presentation.server.ProcessorResponse;
+import org.jboss.portal.presentation.action.server.ShowUIObjectResponse;
+import org.jboss.portal.presentation.action.server.ErrorResponse;
+import org.jboss.portal.presentation.action.server.RedirectResponse;
+import org.jboss.portal.presentation.action.server.StreamResponse;
 
 /**
  * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
@@ -90,15 +85,7 @@
    public ProcessorResponse process(RequestContext requestContext, ProcessorRequest request) throws ServerException
    { 
       try
-      {
-         /*
-         This should process the request sent in from the UIServer using whatever framework the core Portal implements
-         Basically based on the information sent in by the ProcessorRequest this component should have all the information
-         it needs to perform necessary action inside the Portal                 
-         the Processor should use the values sent in the ProcessorRequest object to perform
-         the appropriate action and then send its Response back to the UIServer which should process
-         the Response and sent a Response back to the client
-         */         
+      {                  
          ProcessorResponse response = null;
          
          //For now, just for prototype sake just use the existing Controller to produce the outcome
@@ -109,117 +96,47 @@
          //by the Portal Controller
          ServerInvocation invocation = request.getServerInvocation();
          ServletContextDispatcher dispatcher = new ServletContextDispatcher(invocation.getServerContext().getClientRequest(), 
-         invocation.getServerContext().getClientResponse(), invocation.getRequest().getServer().getServletContainerContext());  
+         invocation.getServerContext().getClientResponse(), invocation.getRequest().getServer().getServletContainerContext());
+         
          String task = (String)invocation.getServerContext().getClientRequest().getAttribute("pfTask");
          if(task.equals("aggregate"))
          {
             //Handle page aggregation and sending result back to the client
-            /*
             MarkupInfo markupInfo = (MarkupInfo)invocation.getResponse().getContentInfo();
             PageResult pageResult = (PageResult)invocation.getServerContext().getClientRequest().getAttribute("pageResult");
-            
-            //Now generate a ProcessorResponse by mapping the data produced during the execution of
-            //the Portal Request
             String contentType = markupInfo.getContentType() + "; charset=" + markupInfo.getCharset();
-            Page pageToBeDisplayed = new Page();
-            pageToBeDisplayed.setCurrentlyDisplayed(true);
             
-            //Setup information inside the page object
-            pageToBeDisplayed.setName(pageResult.getPageName());
-            List windows = this.getWindows(pageResult.getWindowContextMap());
-            if(windows != null)
-            {
-               pageToBeDisplayed.getChildren().addAll(windows);
-            }
-            
-            //
-            List updatedPages = new ArrayList();
-            updatedPages.add(pageToBeDisplayed);
-            
-            //Generate the response to be sent back for processing by the Presentation Framework
-            response = new ProcessorResponse(dispatcher, contentType, markupInfo.getCharset(), updatedPages);
-            */
+            //Generate the response to be sent back for processing by the Presentation Framework 
+            response = new ProcessorResponse(dispatcher, null);
          }
          else if(task.equals("stream"))
          {
             //Handle sending back binary content back to the client
             String contentType = (String)invocation.getServerContext().getClientRequest().getAttribute("contentType");
-            InputStream in = (InputStream)invocation.getServerContext().getClientRequest().getAttribute("inputStream");
-            
-            //Process and see if binary content needs to be sent back...
-            //In this case write the response to the OutputStream directly
-            //There is no need for any Presentation Framework processing            
-            if(contentType != null && in != null)
-            {
-               HttpServletResponse resp = invocation.getServerContext().getClientResponse();
-               resp.setContentType(contentType);
-               ServletOutputStream sout = null;
-               try
-               {
-                  sout = resp.getOutputStream();
-                  byte[] buf = new byte[2048];
-                  int len;
-                  while ((len = in.read(buf)) > 0)
-                  {
-                     sout.write(buf, 0, len);
-                  }
-                  sout.flush();
-               }
-               finally
-               {
-                  IOTools.safeClose(in);
-                  IOTools.safeClose(sout);
-               }
-            }
+            InputStream in = (InputStream)invocation.getServerContext().getClientRequest().getAttribute("inputStream");            
+            StreamResponse streamResponse = new StreamResponse(contentType, in);
+            response = new ProcessorResponse(dispatcher, streamResponse);
          }
          else if(task.equals("redirect"))
          {
             //Handle sendRedirect back to the client
             String url = (String)invocation.getServerContext().getClientRequest().getAttribute("url");
-            invocation.getServerContext().getClientResponse().sendRedirect(url);            
+            RedirectResponse redirectResponse = new RedirectResponse(url);
+            response = new ProcessorResponse(dispatcher, redirectResponse);
          }
          else if(task.equals("error"))
          {
             //Handle sendingErrror back to the client
             Integer errorCode = (Integer)invocation.getServerContext().getClientRequest().getAttribute("errorCode");
-            invocation.getServerContext().getClientResponse().sendError(errorCode.intValue());
+            ErrorResponse errorResponse = new ErrorResponse(errorCode.intValue());
+            response = new ProcessorResponse(dispatcher, errorResponse);
          }
-         
-         
+                  
          return response;
       }
       catch(Exception e)
       {
          throw new ServerException(e);
       }
-   }
-   
-   /**
-    * 
-    * @param windowContexts
-    * @return
-    */
-   private List getWindows(Map windowContexts)
-   {
-      List windows = null;
-      
-      /*if(windowContexts != null)
-      {
-         windows = new ArrayList();
-         for(Iterator itr=windowContexts.keySet().iterator(); itr.hasNext();)
-         {
-            String windowId = (String)itr.next();
-            WindowContext windowContext = (WindowContext)windowContexts.get(windowId);
-            WindowResult windowResult = windowContext.getResult();
-            
-            Window window = new Window(windowId, windowResult.getTitle(), 
-            windowResult.getContent(), windowResult.getHeaderContent(), 
-            windowResult.getWindowState(), windowResult.getMode());
-            
-            windows.add(window);
-         }
-      }*/
-      
-      return windows;
-   }
+   }   
 }

Modified: branches/UIServer/core/src/main/org/jboss/portal/core/theme/PageRendition.java
===================================================================
--- branches/UIServer/core/src/main/org/jboss/portal/core/theme/PageRendition.java	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/core/src/main/org/jboss/portal/core/theme/PageRendition.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -43,8 +43,6 @@
 import java.util.List;
 import java.util.ArrayList;
 
-//import org.jboss.portal.presentation.service.UIServer;
-
 /**
  * Should not be a controller response, but it comes from legacy design.
  *
@@ -96,8 +94,6 @@
       //
       RendererContext rendererContext = layout.getRenderContext(themeContext, markupInfo, dispatcher);
       
-      //
-      //This is the non-uiserver based rendering
       try
       {
          rendererContext.render(pageResult);
@@ -105,33 +101,7 @@
       catch (RenderException e)
       {
          e.printStackTrace();
-      }
-      
-      /*
-      //Prototyping with the new ui server delegated rendering
-      UIServer uiServer = new UIServer(); //This will actually be a jmx service...instead of instantiating the UiServer here
-                        
-      //Setup the Windows for the UIServer    
-      List uiWindows = new ArrayList();
-      Map windowContexts = pageResult.getWindowContextMap();      
-      for(Iterator itr=windowContexts.values().iterator();itr.hasNext();)
-      {
-         WindowContext wc = (WindowContext)itr.next();
-         WindowResult result = wc.getResult();  
-         
-         org.jboss.portal.uiserver.protocol.WindowResult uiWindow = new org.jboss.portal.uiserver.protocol.WindowResult(wc.getId(),
-          result.getTitle(), result.getContent(), result.getHeaderContent(), result.getWindowState(), result.getMode()
-         ); 
-         
-         uiWindows.add(uiWindow);
-      }                  
-      
-      //Setup the Page for the UIServer
-      org.jboss.portal.uiserver.protocol.PageResult uiPageResult = new org.jboss.portal.uiserver.protocol.PageResult(this.pageResult.getPageName(), uiWindows); 
-      
-      //Delegate Rendering to the UIServer
-      uiServer.render(new PrintWriter(dispatcher.getResponse().getOutputStream()), uiPageResult);
-      */
+      }      
    }
 
    public PageResult getPageResult()

Modified: branches/UIServer/uiserver/build.xml
===================================================================
--- branches/UIServer/uiserver/build.xml	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/build.xml	2007-11-16 16:47:30 UTC (rev 8976)
@@ -242,22 +242,22 @@
    	  	<path refid="gwt.gwt.classpath"/>
    	    <path refid="mygwt.mygwt.classpath"/>   	      	 
    	  </path>
-   	  <delete dir="${build.resources}/portal-uiserver.war/org.jboss.portal.uiserver.ajax.Portal"/>
+   	  <delete dir="${build.resources}/portal-uiserver.war/org.jboss.portal.presentation.ajax.Portal"/>
 	  <java classpathref="full.gwt.classpath" fork="true" classname="com.google.gwt.dev.GWTCompiler">
 	 	<classpath>
 	 	    <pathelement path="src/main"/>
 	        <pathelement path="src/resources/client/ajax/src"/>
 	    </classpath>
 	    <arg line="-out ${build.resources}/portal-uiserver.war/"/>
-	    <arg line="org.jboss.portal.uiserver.ajax.Portal"/>
+	    <arg line="org.jboss.portal.presentation.ajax.Portal"/>
 	  </java>   	     	     	
    	  <jar jarfile="${build.lib}/portal-uiserver.war">
 	     <fileset dir="${build.resources}/portal-uiserver.war"></fileset>
    	  </jar>
    	  <copy todir="${build.resources}/portal-uiserver.war">
-   	  	<fileset dir="${build.resources}/portal-uiserver.war/org.jboss.portal.uiserver.ajax.Portal"/>
+   	  	<fileset dir="${build.resources}/portal-uiserver.war/org.jboss.portal.presentation.ajax.Portal"/>
    	  </copy>
-   	  <delete dir="${build.resources}/portal-uiserver.war/org.jboss.portal.uiserver.ajax.Portal"/>
+   	  <delete dir="${build.resources}/portal-uiserver.war/org.jboss.portal.presentation.ajax.Portal"/>
    	  
    	
    	  <!-- portal-uiserver.sar -->

Modified: branches/UIServer/uiserver/gwt-dev-env/AsyncPages(uiserver).launch
===================================================================
--- branches/UIServer/uiserver/gwt-dev-env/AsyncPages(uiserver).launch	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/gwt-dev-env/AsyncPages(uiserver).launch	2007-11-16 16:47:30 UTC (rev 8976)
@@ -13,7 +13,7 @@
 <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;UIServer&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
 <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/UIServer/uiserver/gwt-dev-env/gwt-dev-linux.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
 </listAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out www org.jboss.portal.uiserver.ajax.AsyncPages/asyncPages.html"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out www org.jboss.portal.presentation.ajax.AsyncPages/asyncPages.html"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="UIServer"/>
 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
 <listEntry value="/UIServer"/>

Modified: branches/UIServer/uiserver/gwt-dev-env/MyGWT(uiserver).launch
===================================================================
--- branches/UIServer/uiserver/gwt-dev-env/MyGWT(uiserver).launch	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/gwt-dev-env/MyGWT(uiserver).launch	2007-11-16 16:47:30 UTC (rev 8976)
@@ -14,7 +14,7 @@
 <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/UIServer/uiserver/gwt-dev-env/gwt-dev-linux.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
 <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/UIServer/uiserver/gwt-dev-env/mygwt.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
 </listAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out www org.jboss.portal.uiserver.ajax.MyGWT/mygwt.html"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out www org.jboss.portal.presentation.ajax.MyGWT/mygwt.html"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="UIServer"/>
 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
 <listEntry value="/UIServer"/>

Modified: branches/UIServer/uiserver/gwt-dev-env/PartialRefresh(uiserver).launch
===================================================================
--- branches/UIServer/uiserver/gwt-dev-env/PartialRefresh(uiserver).launch	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/gwt-dev-env/PartialRefresh(uiserver).launch	2007-11-16 16:47:30 UTC (rev 8976)
@@ -13,7 +13,7 @@
 <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;UIServer&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
 <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/UIServer/uiserver/gwt-dev-env/gwt-dev-linux.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
 </listAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out www org.jboss.portal.uiserver.ajax.PartialRefresh/partialRefresh.html"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out www org.jboss.portal.presentation.ajax.PartialRefresh/partialRefresh.html"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="UIServer"/>
 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
 <listEntry value="/UIServer"/>

Modified: branches/UIServer/uiserver/gwt-dev-env/Portal(uiserver).launch
===================================================================
--- branches/UIServer/uiserver/gwt-dev-env/Portal(uiserver).launch	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/gwt-dev-env/Portal(uiserver).launch	2007-11-16 16:47:30 UTC (rev 8976)
@@ -13,7 +13,7 @@
 <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;UIServer&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
 <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/UIServer/uiserver/gwt-dev-env/gwt-dev-linux.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
 </listAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out www org.jboss.portal.uiserver.ajax.Portal/index.html"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out www org.jboss.portal.presentation.ajax.Portal/index.html"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="UIServer"/>
 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
 <listEntry value="/UIServer"/>

Modified: branches/UIServer/uiserver/gwt-dev-env/PortalLayout(uiserver).launch
===================================================================
--- branches/UIServer/uiserver/gwt-dev-env/PortalLayout(uiserver).launch	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/gwt-dev-env/PortalLayout(uiserver).launch	2007-11-16 16:47:30 UTC (rev 8976)
@@ -13,7 +13,7 @@
 <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;UIServer&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
 <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/UIServer/uiserver/gwt-dev-env/gwt-dev-linux.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
 </listAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out www org.jboss.portal.uiserver.ajax.PortalLayout/layout.html"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out www org.jboss.portal.presentation.ajax.PortalLayout/layout.html"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="UIServer"/>
 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
 <listEntry value="/UIServer"/>

Modified: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/ErrorResponse.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/ErrorResponse.java	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/ErrorResponse.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -28,4 +28,26 @@
  */
 public class ErrorResponse extends ServerResponse
 {
+   /**
+    * 
+    */
+   private int errorCode = 0;
+   
+   /**
+    * 
+    * @param errorCode
+    */
+   public ErrorResponse(int errorCode)
+   {
+      this.errorCode = errorCode;
+   }
+   
+   /**
+    * 
+    * @return
+    */
+   public int getErrorCode()
+   {
+      return this.errorCode;
+   }
 }

Modified: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/LinkActivation.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/LinkActivation.java	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/LinkActivation.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -24,8 +24,8 @@
 
 import java.util.Map;
 
-import org.jboss.portal.presentation.model.Portal;
-import org.jboss.portal.presentation.model.PortalObject;
+import org.jboss.portal.presentation.model.UIPortal;
+import org.jboss.portal.presentation.model.UIObject;
 
 /**
  * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
@@ -51,12 +51,12 @@
    /**
     * The Portal that the target object belongs to
     */
-   protected Portal portal = null;
+   protected UIPortal portal = null;
    
    /**
     * Target object where action needs to be performed
     */
-   protected PortalObject target = null;
+   protected UIObject target = null;
 
    /**
     * 
@@ -116,7 +116,7 @@
     * 
     * @return
     */
-   public Portal getPortal()
+   public UIPortal getPortal()
    {
       return portal;
    }
@@ -125,7 +125,7 @@
     * 
     * @param portal
     */
-   public void setPortal(Portal portal)
+   public void setPortal(UIPortal portal)
    {
       this.portal = portal;
    }
@@ -134,7 +134,7 @@
     * 
     * @return
     */
-   public PortalObject getTarget()
+   public UIObject getTarget()
    {
       return target;
    }
@@ -143,7 +143,7 @@
     * 
     * @param target
     */
-   public void setTarget(PortalObject target)
+   public void setTarget(UIObject target)
    {
       this.target = target;
    }

Modified: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/RedirectResponse.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/RedirectResponse.java	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/RedirectResponse.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -26,7 +26,7 @@
  * @author <a href="mailto:julien at jboss.org">Julien Viet</a>
  * @version $Revision: 1.1 $
  */
-public class RedirectResponse
+public class RedirectResponse extends ServerResponse
 {
 
    /** . */

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/StreamResponse.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/StreamResponse.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/action/server/StreamResponse.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.action.server;
+
+import java.io.InputStream;
+
+/**
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public class StreamResponse extends ServerResponse
+{
+   /**
+    * 
+    */
+   private String contentType = null;
+   
+   /**
+    * 
+    */
+   private InputStream is = null;
+   
+   /**
+    * 
+    * @param contentType
+    * @param is
+    */
+   public StreamResponse(String contentType, InputStream is)
+   {
+      this.contentType = contentType;
+      this.is = is;
+   }
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/AsyncPages.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/AsyncPages.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/AsyncPages.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,566 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.ajax.client;
+
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.EntryPoint;
+
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.HTTPRequest;
+import com.google.gwt.user.client.ResponseTextHandler;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.user.client.ui.ClickListener;
+import com.google.gwt.user.client.ui.TabBar;
+import com.google.gwt.user.client.ui.TabListener;
+import com.google.gwt.user.client.ui.SourcesTabEvents;
+
+import com.google.gwt.user.client.rpc.ServiceDefTarget;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import net.mygwt.ui.client.widget.ContentPanel;
+import net.mygwt.ui.client.widget.IconButton;
+import net.mygwt.ui.client.widget.WidgetContainer;
+import net.mygwt.ui.client.widget.Viewport;
+import net.mygwt.ui.client.widget.layout.*;
+import net.mygwt.ui.client.Style;
+import net.mygwt.ui.client.event.Listener;
+import net.mygwt.ui.client.event.BaseEvent;
+
+import org.jboss.portal.presentation.ajax.client.protocol.Page;
+import org.jboss.portal.presentation.ajax.client.protocol.Window;
+
+/**
+ * Used for Prototyping Async Page Management
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public class AsyncPages implements EntryPoint
+{
+   /**
+    * 
+    */
+   private Viewport viewport = null;
+   
+   /**
+    * 
+    */
+   private WidgetContainer north = null;
+   
+   /**
+    * 
+    */
+   private WidgetContainer west = null;
+   
+   /**
+    * 
+    */
+   private WidgetContainer center = null;
+   
+   
+   /**
+    * This is the entry point method.
+    */
+   public void onModuleLoad()
+   {       
+      //Initialize the Viewport
+      this.viewport = new Viewport();
+      
+      //Layout for the viewport
+      BorderLayout pageLayout = new BorderLayout();
+            
+      //Layout for the north region (Header/Navigation related content produced by the portal are laid out here)
+      FlowLayout northLayout = new FlowLayout();
+      
+      //Setup the layout of the root container of the page
+      this.viewport.setLayout(pageLayout);
+      
+      //Setup the north region of the page
+      this.north = new WidgetContainer();
+      this.north.setLayout(northLayout);
+      float northSize = this.viewport.getOffsetHeight() * ((float)0.05);
+      BorderLayoutData northData = new BorderLayoutData(Style.NORTH, northSize);
+      northData.resizeable = true;
+      this.viewport.add(this.north, northData);      
+      
+      //Load the navigation bar....use a tabbed bar
+      TabBar pageNavigator = new TabBar();
+      pageNavigator.addTab("Page 1");
+      pageNavigator.addTab("Page 2");
+      pageNavigator.addTab("Page 3");
+      pageNavigator.selectTab(0); 
+      pageNavigator.addTabListener(new TabListenerImpl());
+      this.north.add(pageNavigator);
+            
+      //Load the Portal Page
+      this.loadPartialRefreshPage("Page 1");
+   }
+      
+   /**
+    * 
+    *
+    */
+   private void loadPartialRefreshPage(String pageId)
+   {      
+      PortletServiceAsync portletService = (PortletServiceAsync)GWT.create(PortletService.class);      
+      ((ServiceDefTarget)portletService).setServiceEntryPoint(GWT.getModuleBaseURL()+"/portletService");
+            
+      AsyncCallback callback = new AsyncCallback()
+      {
+         public void onSuccess(Object result)
+         {
+            Page portalPage = (Page)result;
+            displayPortalPage(portalPage);
+         }
+         
+         public void onFailure(Throwable caught)
+         {
+         }
+      };
+      
+      portletService.getPage(pageId, callback);      
+   }
+   
+   /**
+    * 
+    * @param portalPage
+    */
+   private void displayPortalPage(Page portalPage)
+   {          
+      //A Viewport resizing listener
+      
+      
+      //Dispalying the fully aggregated page
+      Window[] windows = portalPage.getWindows();  
+      int column = 0;
+      
+      this.setUpPortletRegions();
+            
+      //Fill up the page with portlet windows
+      for(int i=0; i<windows.length; i++)
+      {
+         Window pageWindow = windows[i]; 
+         if(pageWindow.isVisible())
+         {                                                            
+            //Add this window to the Page
+            if(column == 0 && windows.length>1)
+            {
+               this.west.add(this.getPortletWindow(pageWindow.getName(), pageWindow.getContent()));
+               column ++;
+            }
+            else
+            {
+               this.center.add(this.getPortletWindow(pageWindow.getName(), pageWindow.getContent()));               
+               column = 0;
+            }
+         }
+      } 
+      
+      //render the page
+      this.viewport.layout(true);
+   }  
+   
+   /**
+    * 
+    * @param content
+    * @return
+    */
+   private ContentPanel getPortletWindow(String windowName, String content)
+   {
+      ContentPanel portletWindow = new ContentPanel(Style.HEADER);
+      portletWindow.setId(windowName);
+      HTML windowContent = new HTML(content);                                                              
+      
+      
+      //Setup listeners
+      //Event Listener for the decoration components like
+      //Normal, Maximized, Minimized
+      Listener listener = new Listener()
+      {
+         public void handleEvent(BaseEvent event)
+         {   
+            IconButton cour = (IconButton)event.widget;
+            String id = cour.getId();            
+            String windowName = id.substring(0, id.indexOf(':'));
+            String action = id.substring(id.indexOf(':')+1);
+            if(action.equals("restore"))
+            {
+               handleWindowStateChanged(windowName, Window.NORMAL);
+            }
+            else if(action.equals("minimize"))
+            {
+               handleWindowStateChanged(windowName, Window.MINIMIZED);
+            }
+            else if(action.equals("maximize"))
+            {
+               handleWindowStateChanged(windowName, Window.MAXIMIZED);
+            }
+            else if(action.equals("save"))
+            {
+               handleWindowModeChanged(windowName, Window.EDIT);
+            }
+         } 
+      };
+      IconButton save = new IconButton("my-tool-save");
+      save.setId(windowName+":save");
+      IconButton help = new IconButton("my-tool-help");
+      help.setId(windowName+":help");
+      IconButton restore = new IconButton("my-tool-restore");
+      restore.setId(windowName+":restore");
+      IconButton minimize = new IconButton("my-tool-minimize");
+      minimize.setId(windowName+":minimize");
+      IconButton maximize = new IconButton("my-tool-maximize");
+      maximize.setId(windowName+":maximize");
+      portletWindow.addButton(save, listener);
+      portletWindow.addButton(help, listener);
+      portletWindow.addButton(restore, listener);
+      portletWindow.addButton(minimize, listener);
+      portletWindow.addButton(maximize, listener);
+      
+      //Event Listener for actions perfomed inside the portlet window content
+      //itself.
+      ClickListener contentListener = new ClickListener()
+      {
+         public void onClick(Widget sender)
+         {
+            Event event = DOM.eventGetCurrentEvent();
+            Element target = DOM.eventGetTarget(event);
+                        
+            if(target.toString().toUpperCase().trim().indexOf("</A>") != -1)
+            {               
+               String link = DOM.getElementAttribute(target, "HREF");
+               
+               //A link inside the portlet window was clicked
+               //Load its content asynchronously inside this window
+               boolean isPartialRefreshAllowed = isPartialRefreshAllowed(link);               
+               if(isPartialRefreshAllowed)
+               {
+                  DOM.eventPreventDefault(event);
+                  handlePartialRefreshLink(link, sender);
+               }
+            }
+            else if(target.toString().toUpperCase().trim().indexOf("INPUT") != -1 &&
+                    target.toString().toUpperCase().trim().indexOf("SUBMIT") != -1
+            )
+            {               
+               Element currentForm = DOM.getParent(target);
+               String enctype = DOM.getElementAttribute(currentForm, "enctype");
+               String action = DOM.getElementAttribute(currentForm, "action");
+               boolean isPartialRefreshAllowed = isPartialRefreshAllowed(action);
+               if((isPartialRefreshAllowed) && (enctype == null || !enctype.equals("multipart/form-data")))
+               {
+                  DOM.eventPreventDefault(event);
+                  
+                  //Call a native javascript function here                  
+                  String method = DOM.getElementAttribute(currentForm, "method");                  
+                  String serializedForm = serializeForm(currentForm);   
+                  
+                  handlePartialRefreshForm(action, method, serializedForm, sender);
+               }
+            }
+         } 
+      };
+      windowContent.addClickListener(contentListener);
+      
+      //Add the content
+      portletWindow.add(windowContent);
+      
+      return portletWindow;
+   }
+   
+   /**
+    * 
+    *
+    */
+   private void setUpPortletRegions()
+   {
+      if(this.west != null)
+      {
+         this.viewport.remove(this.west);
+      }
+      if(this.center != null)
+      {
+         this.viewport.remove(this.center);
+      }
+      
+      //Re-add these two regions
+      //Layout for the west region (Portlet Windows are laid out here)
+      FlowLayout westLayout = new FlowLayout();
+      westLayout.spacing = 5;
+      westLayout.margin = 5;
+      
+      //Layout for the center region (Portlet Windows are laid out here)
+      FlowLayout centerLayout = new FlowLayout();
+      centerLayout.spacing = 5;
+      centerLayout.margin = 5;
+      
+      //Setup the west region of the page
+      this.west = new WidgetContainer();
+      this.west.setScrollEnabled(true);
+      this.west.setLayout(westLayout);      
+      float westSize = this.viewport.getOffsetWidth() * ((float)0.2);  
+      BorderLayoutData westData = new BorderLayoutData(Style.WEST, westSize);
+      westData.resizeable = true;
+      this.viewport.add(this.west, westData);
+      
+      //Setup the center region of the page
+      this.center = new WidgetContainer();
+      this.center.setScrollEnabled(true);
+      this.center.setLayout(centerLayout);
+      BorderLayoutData centerData = new BorderLayoutData(Style.CENTER);
+      centerData.resizeable = true;
+      this.viewport.add(this.center, centerData);
+   }
+   
+   /**
+    * 
+    * @param window
+    * @param newState
+    */
+   private void handleWindowStateChanged(String window, String newState)
+   {
+      PortletServiceAsync portletService = (PortletServiceAsync)GWT.create(PortletService.class);      
+      ((ServiceDefTarget)portletService).setServiceEntryPoint(GWT.getModuleBaseURL()+"/portletService");
+      
+      AsyncCallback callback = new AsyncCallback()
+      {
+         public void onSuccess(Object result)
+         {  
+            Page portalPage = (Page)result;
+            displayPortalPage(portalPage);
+         }
+         
+         public void onFailure(Throwable caught)
+         {
+         }
+      };
+      
+      portletService.setState(window, newState, callback);
+   }
+   
+   /**
+    * 
+    * @param window
+    * @param newState
+    */
+   private void handleWindowModeChanged(String window, String newMode)
+   {
+      PortletServiceAsync portletService = (PortletServiceAsync)GWT.create(PortletService.class);      
+      ((ServiceDefTarget)portletService).setServiceEntryPoint(GWT.getModuleBaseURL()+"/portletService");
+      
+      AsyncCallback callback = new AsyncCallback()
+      {
+         public void onSuccess(Object result)
+         {  
+            Page portalPage = (Page)result;
+            displayPortalPage(portalPage);
+         }
+         
+         public void onFailure(Throwable caught)
+         {
+         }
+      };
+      
+      portletService.setMode(window, newMode, callback);
+   }
+   
+   /**
+    * 
+    * @param url
+    * @param portletWindow
+    */
+   private void handlePartialRefreshLink(String url, Widget windowContent)
+   {
+      HTTPRequest.asyncGet(url, new ResponseTextHandlerImpl(windowContent));
+   }
+   
+   /**
+    * 
+    * @param url
+    * @param portletWindow
+    */
+   private void handlePartialRefreshForm(String url, String method, String postData, Widget windowContent)
+   {                  
+      if(method.equalsIgnoreCase("post"))
+      {
+         HTTPRequest.asyncPost(url, postData, new ResponseTextHandlerImpl(windowContent));
+      }
+      else if(method.equalsIgnoreCase("get"))
+      {
+         if(postData != null && postData.trim().length() > 0)
+         {
+            url = url + "?" + postData;
+         }
+         HTTPRequest.asyncGet(url, new ResponseTextHandlerImpl(windowContent));
+      }
+   }
+   
+   /**
+    * 
+    * @author soshah
+    *
+    */
+   private class ResponseTextHandlerImpl implements ResponseTextHandler
+   {
+      private Widget windowContent = null;
+      
+      public ResponseTextHandlerImpl(Widget windowContent)
+      {
+         this.windowContent = windowContent;
+      }      
+      public void onCompletion(String responseText)
+      {
+         HTML html = new HTML(responseText);          
+         ContentPanel window =  (ContentPanel)this.windowContent.getParent();
+         window.remove(this.windowContent);
+         window.add(html);
+         window.layout(true);
+      } 
+   }
+   
+   /**
+    * 
+    * @param url
+    * @return
+    */
+   private boolean isPartialRefreshAllowed(String url)
+   {      
+      String basePortalURL = GWT.getModuleBaseURL();
+      String portalContext = "org.jboss.portal.presentation.Portal"; //This is hard coded for now, but must be populated from the Portal deployment environment
+      //If Portal is installed at Root context, this value will be an empty string
+      
+      if(url == null)
+      {
+         return false;
+      }
+      
+      if(url.startsWith(basePortalURL))
+      {
+         //This is an Absolute URL, but it points back to
+         //the Portal
+         //An Async Page Refresh call should be allowed in this case
+         return true;
+      }
+      
+      if(url.startsWith("http://"))
+      {
+         //This is an Absolute URL and does not point back
+         //to the Portal
+         //Async Page Refresh call should not be allowed
+         return false;
+      }
+      else
+      {
+         //This is a relative URL. 
+         
+         //Make sure it points back to the Portal for an Async Page Refresh        
+         //If it points to some other resource like another third-party web application etc, the response
+         //has nothing to do with Portal 
+         //(unless ofcourse the client side processor of the Portal, wants to
+         //take this response and aggregate this inside the current Portal Page and Window being displayed. This is an exceptional usecase
+         //and not desired behavior for every scenario from end user standpoint)
+         //As standard behavior, Async Page Refresh to be done, only when Portlet Markup is sending a request back to the Portal         
+         if(url.startsWith("/"))
+         {
+            if(!portalContext.equals(""))
+            {
+               String urlContext = null;
+               int index = url.indexOf('/', 1);
+               if(index != -1)
+               {
+                  urlContext = url.substring(1, index);
+               }
+               else
+               {
+                  urlContext = url.substring(1);
+               }
+               
+               if(!portalContext.equals(urlContext))
+               { 
+                  //This request is not being sent to the Portal. It is being sent to some other web application
+                  return false;
+               }
+            }
+            else
+            {
+               //If Portal is running on root context, there is no way to tell from client side, if this request is actually
+               //to be sent to the Portal or some other web application. Hence, in the interest of functional safety/correctness
+               //no Async Page Refresh here
+               //If Portal is running on Root context, Partial Refresh will happen only for pure relative links
+               return false;
+            }
+         }
+         
+         //If I get here, Async Page Refresh through the Portal should be allowed
+         return true;
+      }
+   }
+   
+   /**
+    * 
+    * @param currentForm
+    * @return
+    */
+   public native String serializeForm(Element currentForm) 
+   /*-{      
+      var formData = $wnd.Form.serialize(currentForm);
+      return formData;
+   }-*/;   
+   //------------Page Navigation related logic-----------------------------------------------------------------------------------------------------
+   /**
+    * 
+    */
+   private class TabListenerImpl implements TabListener
+   {
+      /**
+       * 
+       */
+      public boolean onBeforeTabSelected(SourcesTabEvents sender, int tabIndex)
+      {
+         return true;
+      }
+
+      /**
+       * 
+       */
+      public void onTabSelected(SourcesTabEvents sender, int tabIndex)
+      {
+         if(tabIndex == 0)
+         {
+            loadPartialRefreshPage("Page 1");
+         }
+         else if(tabIndex == 1)
+         {
+            loadPartialRefreshPage("Page 2");
+         }
+         else if(tabIndex == 2)
+         {
+            loadPartialRefreshPage("Page 3");
+         }
+      }      
+   }
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/MyGWTPrototype.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/MyGWTPrototype.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/MyGWTPrototype.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,114 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.ajax.client;
+
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.HTML;
+
+import net.mygwt.ui.client.Style;
+import net.mygwt.ui.client.event.BaseEvent;  
+import net.mygwt.ui.client.event.SelectionListener;  
+import net.mygwt.ui.client.widget.Button;
+import net.mygwt.ui.client.widget.IconButton;
+import net.mygwt.ui.client.widget.ButtonBar;  
+import net.mygwt.ui.client.widget.Info;
+import net.mygwt.ui.client.widget.ContentPanel;
+
+/**
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ * 
+ */
+public class MyGWTPrototype implements EntryPoint
+{
+   /**
+    * 
+    */
+   public void onModuleLoad()
+   {
+      VerticalPanel panel = new VerticalPanel();
+      RootPanel.get("currentPage").add(panel);
+
+      // Fillup panel with MyGWT widgets for testing
+      this.createButtonWidget(panel);
+      this.createPortletWindowWidget(panel);
+   }
+
+   /**
+    * 
+    * @param container
+    */
+   private void createButtonWidget(VerticalPanel panel)
+   {
+      SelectionListener listener = new SelectionListener()
+      {
+         public void widgetSelected(BaseEvent be)
+         {
+            Button btn = (Button) be.widget;
+            Info.show("Click Event", "The '{0}' button was clicked.", btn
+                  .getText());
+         }
+      };
+
+      ButtonBar buttonBar = new ButtonBar(Style.LEFT);
+      buttonBar.add(new Button("Click Me", listener));
+
+      Button iconBtn = new Button("Icon Button", listener);
+      iconBtn.setIconStyle("window-maximize-button");
+      buttonBar.add(iconBtn);
+
+      Button disabled = new Button("Disabled", listener);
+      disabled.setEnabled(false);
+      buttonBar.add(disabled);
+      
+      panel.add(buttonBar);
+   }
+   
+   /**
+    * 
+    * @param panel
+    */
+   private void createPortletWindowWidget(VerticalPanel panel)
+   {
+      HTML html = new HTML("<div class=\"window-normal-button\">Normal</div><br/><div class=\"window-minimize-button\">Minimize</div><br/><div class=\"window-maximize-button\">Maximize</div>");
+      
+      ContentPanel contentPanel = new ContentPanel(Style.HEADER);     
+      contentPanel.addButton(new IconButton("my-tool-save"), null);
+      contentPanel.addButton(new IconButton("my-tool-help"), null);
+      contentPanel.addButton(new IconButton("my-tool-restore"), null);
+      contentPanel.addButton(new IconButton("my-tool-minimize"), null);
+      contentPanel.addButton(new IconButton("my-tool-maximize"), null);
+      
+      Button normalButton = new Button("", null);
+      normalButton.setIconStyle("window-normal-button");
+      
+      IconButton iconNormalButton = new IconButton("window-minimize-button");
+      
+      contentPanel.add(html); 
+      contentPanel.add(normalButton);
+      contentPanel.add(iconNormalButton);
+            
+      panel.add(contentPanel);
+   }
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PartialRefresh.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PartialRefresh.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PartialRefresh.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,410 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.ajax.client;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.EntryPoint;
+
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.HTTPRequest;
+import com.google.gwt.user.client.ResponseTextHandler;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.ClickListener;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Panel;
+
+import com.google.gwt.user.client.rpc.ServiceDefTarget;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import org.jboss.portal.presentation.ajax.client.protocol.Page;
+import org.jboss.portal.presentation.ajax.client.protocol.Window;
+
+/**
+ * Used for Prototyping Partial Refresh feature
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public class PartialRefresh implements EntryPoint
+{
+   /**
+    * This is the entry point method.
+    */
+   public void onModuleLoad()
+   {             
+      //Proof of Concept for Portlet Partial Refresh feature
+      this.testPartialRefresh();
+   }
+   
+   /**
+    * 
+    *
+    */
+   private void testPartialRefresh()
+   {
+      VerticalPanel page = new VerticalPanel();
+      RootPanel.get("page").add(page);
+      
+      this.loadPartialRefreshPage();
+   }
+   
+   /**
+    * 
+    *
+    */
+   private void loadPartialRefreshPage()
+   {      
+      PortletServiceAsync portletService = (PortletServiceAsync)GWT.create(PortletService.class);      
+      ((ServiceDefTarget)portletService).setServiceEntryPoint(GWT.getModuleBaseURL()+"/portletService");
+            
+      AsyncCallback callback = new AsyncCallback()
+      {
+         public void onSuccess(Object result)
+         {
+            Page portalPage = (Page)result;
+            displayPortalPage(portalPage);
+         }
+         
+         public void onFailure(Throwable caught)
+         {
+         }
+      };
+      
+      portletService.getPage("index", callback);      
+   }
+   
+   /**
+    * 
+    * @param window
+    * @param newState
+    */
+   private void handleWindowStateChanged(String window, String newState)
+   {
+      PortletServiceAsync portletService = (PortletServiceAsync)GWT.create(PortletService.class);      
+      ((ServiceDefTarget)portletService).setServiceEntryPoint(GWT.getModuleBaseURL()+"/portletService");
+      
+      AsyncCallback callback = new AsyncCallback()
+      {
+         public void onSuccess(Object result)
+         {  
+            Page portalPage = (Page)result;
+            displayPortalPage(portalPage);
+         }
+         
+         public void onFailure(Throwable caught)
+         {
+         }
+      };
+      
+      portletService.setState(window, newState, callback);
+   }
+   
+   /**
+    * 
+    * @param window
+    * @param newState
+    */
+   private void handleWindowModeChanged(String window, String newMode)
+   {
+      PortletServiceAsync portletService = (PortletServiceAsync)GWT.create(PortletService.class);      
+      ((ServiceDefTarget)portletService).setServiceEntryPoint(GWT.getModuleBaseURL()+"/portletService");
+      
+      AsyncCallback callback = new AsyncCallback()
+      {
+         public void onSuccess(Object result)
+         {  
+            Page portalPage = (Page)result;
+            displayPortalPage(portalPage);
+         }
+         
+         public void onFailure(Throwable caught)
+         {
+         }
+      };
+      
+      portletService.setMode(window, newMode, callback);
+   }
+   
+   /**
+    * 
+    * @param url
+    * @param portletWindow
+    */
+   private void handlePartialRefreshLink(String url, Widget windowContent)
+   {
+      HTTPRequest.asyncGet(url, new ResponseTextHandlerImpl(windowContent));
+   }
+   
+   /**
+    * 
+    * @param url
+    * @param portletWindow
+    */
+   private void handlePartialRefreshForm(String url, String method, String postData, Widget windowContent)
+   {                  
+      if(method.equalsIgnoreCase("post"))
+      {
+         HTTPRequest.asyncPost(url, postData, new ResponseTextHandlerImpl(windowContent));
+      }
+      else if(method.equalsIgnoreCase("get"))
+      {
+         if(postData != null && postData.trim().length() > 0)
+         {
+            url = url + "?" + postData;
+         }
+         HTTPRequest.asyncGet(url, new ResponseTextHandlerImpl(windowContent));
+      }
+   }
+   
+   /**
+    * 
+    * @author soshah
+    *
+    */
+   private static class ResponseTextHandlerImpl implements ResponseTextHandler
+   {
+      private Widget windowContent = null;
+      
+      public ResponseTextHandlerImpl(Widget windowContent)
+      {
+         this.windowContent = windowContent;
+      }      
+      public void onCompletion(String responseText)
+      {
+         HTML html = new HTML(responseText);          
+         Panel window =  (Panel)this.windowContent.getParent();
+         this.windowContent.removeFromParent();
+         window.add(html);
+      } 
+   }
+   
+   /**
+    * 
+    * @param url
+    * @return
+    */
+   private boolean isPartialRefreshAllowed(String url)
+   {      
+      String basePortalURL = GWT.getModuleBaseURL();
+      String portalContext = "org.jboss.portal.presentation.Portal"; //This is hard coded for now, but must be populated from the Portal deployment environment
+      //If Portal is installed at Root context, this value will be an empty string
+      
+      if(url.startsWith(basePortalURL))
+      {
+         //This is an Absolute URL, but it points back to
+         //the Portal
+         //An Async Page Refresh call should be allowed in this case
+         return true;
+      }
+      
+      if(url.startsWith("http://"))
+      {
+         //This is an Absolute URL and does not point back
+         //to the Portal
+         //Async Page Refresh call should not be allowed
+         return false;
+      }
+      else
+      {
+         //This is a relative URL. 
+         
+         //Make sure it points back to the Portal for an Async Page Refresh        
+         //If it points to some other resource like another third-party web application etc, the response
+         //has nothing to do with Portal 
+         //(unless ofcourse the client side processor of the Portal, wants to
+         //take this response and aggregate this inside the current Portal Page and Window being displayed. This is an exceptional usecase
+         //and not desired behavior for every scenario from end user standpoint)
+         //As standard behavior, Async Page Refresh to be done, only when Portlet Markup is sending a request back to the Portal         
+         if(url.startsWith("/"))
+         {
+            if(!portalContext.equals(""))
+            {
+               String urlContext = null;
+               int index = url.indexOf('/', 1);
+               if(index != -1)
+               {
+                  urlContext = url.substring(1, index);
+               }
+               else
+               {
+                  urlContext = url.substring(1);
+               }
+               
+               if(!portalContext.equals(urlContext))
+               { 
+                  //This request is not being sent to the Portal. It is being sent to some other web application
+                  return false;
+               }
+            }
+            else
+            {
+               //If Portal is running on root context, there is no way to tell from client side, if this request is actually
+               //to be sent to the Portal or some other web application. Hence, in the interest of functional safety/correctness
+               //no Async Page Refresh here
+               //If Portal is running on Root context, Partial Refresh will happen only for pure relative links
+               return false;
+            }
+         }
+         
+         //If I get here, Async Page Refresh through the Portal should be allowed
+         return true;
+      }
+   }
+   
+   /**
+    * 
+    * @param currentForm
+    * @return
+    */
+   public native String serializeForm(Element currentForm) 
+   /*-{      
+      var formData = $wnd.Form.serialize(currentForm);
+      return formData;
+   }-*/;
+   
+   /**
+    * 
+    * @param portalPage
+    */
+   private void displayPortalPage(Page portalPage)
+   {            
+      //Event Listener for the decoration components like
+      //Normal, Maximized, Minimized
+      ClickListener listener = new ClickListener()
+      {
+         public void onClick(Widget sender)
+         {   
+            Button cour = (Button)sender;
+            String windowName = sender.getParent().getTitle();
+            if(cour.getText().equals("Normal"))
+            {
+               handleWindowStateChanged(windowName, Window.NORMAL);
+            }
+            else if(cour.getText().equals("Minimized"))
+            {
+               handleWindowStateChanged(windowName, Window.MINIMIZED);
+            }
+            else if(cour.getText().equals("Maximized"))
+            {
+               handleWindowStateChanged(windowName, Window.MAXIMIZED);
+            }
+            else if(cour.getText().equals("Edit"))
+            {
+               handleWindowModeChanged(windowName, Window.EDIT);
+            }
+         } 
+      };
+      
+      //Event Listener for actions perfomed inside the portlet window content
+      //itself.
+      ClickListener contentListener = new ClickListener()
+      {
+         public void onClick(Widget sender)
+         {
+            Event event = DOM.eventGetCurrentEvent();
+            Element target = DOM.eventGetTarget(event);
+                        
+            if(target.toString().toUpperCase().trim().indexOf("</A>") != -1)
+            {               
+               String link = DOM.getElementAttribute(target, "HREF");
+               
+               //A link inside the portlet window was clicked
+               //Load its content asynchronously inside this window
+               boolean isPartialRefreshAllowed = isPartialRefreshAllowed(link);               
+               if(isPartialRefreshAllowed)
+               {
+                  DOM.eventPreventDefault(event);
+                  handlePartialRefreshLink(link, sender);
+               }
+            }
+            else if(target.toString().toUpperCase().trim().indexOf("INPUT") != -1 &&
+                    target.toString().toUpperCase().trim().indexOf("SUBMIT") != -1
+            )
+            {               
+               Element currentForm = DOM.getParent(target);
+               String enctype = DOM.getElementAttribute(currentForm, "enctype");
+               String action = DOM.getElementAttribute(currentForm, "action");
+               boolean isPartialRefreshAllowed = isPartialRefreshAllowed(action);
+               if((isPartialRefreshAllowed) && (enctype == null || !enctype.equals("multipart/form-data")))
+               {
+                  DOM.eventPreventDefault(event);
+                  
+                  //Call a native javascript function here                  
+                  String method = DOM.getElementAttribute(currentForm, "method");                  
+                  String serializedForm = serializeForm(currentForm);   
+                  
+                  handlePartialRefreshForm(action, method, serializedForm, sender);
+               }
+            }
+         } 
+      };
+      
+      //Dispalying the fully aggregated page
+      Window[] windows = portalPage.getWindows();
+      VerticalPanel page = (VerticalPanel)RootPanel.get("page").getWidget(0);
+      page.clear();
+      for(int i=0; i<windows.length; i++)
+      {
+         Window pageWindow = windows[i]; 
+         if(pageWindow.isVisible())
+         {
+            VerticalPanel window = new VerticalPanel();
+            
+            //Create the decoration panel
+            HorizontalPanel decoration = new HorizontalPanel();
+            decoration.setTitle(pageWindow.getName());
+                        
+            Button normal = new Button("Normal");            
+            Button minimized = new Button("Minimized");            
+            Button maximized = new Button("Maximized");            
+            Button edit = new Button("Edit");            
+            
+            decoration.add(normal);
+            decoration.add(minimized);
+            decoration.add(maximized);
+            decoration.add(edit);
+            window.add(decoration);
+            
+            //Create the actual content of the portlet to be displayed inside the window
+            HTML windowContent = new HTML(pageWindow.getContent());
+            window.add(windowContent);
+                                                            
+            //Event listeners for this Window
+            normal.addClickListener(listener);
+            minimized.addClickListener(listener);
+            maximized.addClickListener(listener);
+            edit.addClickListener(listener);
+            windowContent.addClickListener(contentListener);
+            
+            //Add this window to the Page
+            page.add(window);            
+         }
+      }
+   }   
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/Portal.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/Portal.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/Portal.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,94 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.ajax.client;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.user.client.rpc.ServiceDefTarget;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+
+import org.jboss.portal.presentation.ajax.client.service.PortalRPC;
+import org.jboss.portal.presentation.ajax.client.service.PortalRPCAsync;
+import org.jboss.portal.presentation.ajax.client.protocol.Page;
+import org.jboss.portal.presentation.ajax.client.protocol.Window;
+import org.jboss.portal.presentation.ajax.client.widget.PortletWindow;
+import org.jboss.portal.presentation.ajax.client.layout.LayoutManager;
+
+/**
+ * This is the Entry Point of the client-side Ajax agent of the Presentation Framework
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public class Portal implements EntryPoint
+{   
+   /**
+    * This is the entry point method.
+    */
+   public void onModuleLoad()
+   {             
+      PortalRPCAsync portalRPC = (PortalRPCAsync)GWT.create(PortalRPC.class);      
+      ((ServiceDefTarget)portalRPC).setServiceEntryPoint(GWT.getModuleBaseURL()+"/portalrpc");            
+      AsyncCallback callback = new AsyncCallback()
+      {
+         public void onSuccess(Object result)
+         {
+            Page portalPage = (Page)result;
+            displayPortalPage(portalPage);
+         }
+         
+         public void onFailure(Throwable caught)
+         {
+         }
+      };      
+      portalRPC.loadPortal(callback);
+   }     
+   
+   /**
+    * 
+    * @param portalPage
+    */
+   private void displayPortalPage(Page portalPage)
+   {      
+      //Dispalying the fully aggregated page
+      Window[] windows = portalPage.getWindows();
+      if(windows != null && windows.length>0)
+      {
+         List displayWindows = new ArrayList();
+         for(int i=0; i<windows.length; i++)
+         {
+            Window pageWindow = windows[i]; 
+            if(pageWindow.isVisible())
+            {
+               PortletWindow portletWindow = new PortletWindow(pageWindow);
+               displayWindows.add(portletWindow);
+            }
+         }
+         LayoutManager.doLayout(displayWindows);
+      }      
+   }              
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortalLayout.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortalLayout.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortalLayout.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,181 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.ajax.client;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.EntryPoint;
+
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.HTMLPanel;
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.ClickListener;
+import com.google.gwt.user.client.ui.Widget;
+
+import com.google.gwt.user.client.rpc.ServiceDefTarget;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+/**
+ * Prototyping some client side layout concepts
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public class PortalLayout implements EntryPoint
+{
+   private String leftContent = "<div><table border=\"1\"><tr><td><b>Left Content</b></td></tr></table></div>";
+   private String centerContent = "<div><table border=\"1\"><tr><td><b>Center Content</b></td></tr></table></div>";
+   private String rightContent = "<div><table border=\"1\"><tr><td><b>Right Content</b></td></tr></table></div>";
+
+   /**
+    * This is the entry point method.
+    */
+   public void onModuleLoad()
+   {       
+      //Lets do a Proof of Concept of Layout capabilities that can be obtained using GWT
+      this.testLayout();      
+   }
+   
+   
+   
+   /**
+    * 
+    */
+   private void testLayout()
+   {
+      this.performVerticalColumnLayout();         
+      this.performFlexibleGridLayout();    
+      this.createPortletButtons();
+   }
+   
+   
+   /**
+    * 
+    *
+    */
+   private void performVerticalColumnLayout()
+   {
+      VerticalPanel leftPanel = new VerticalPanel();
+      leftPanel.add(new HTMLPanel(leftContent));
+      leftPanel.add(new HTMLPanel(leftContent));
+      
+      VerticalPanel centerPanel = new VerticalPanel();
+      centerPanel.add(new HTMLPanel(centerContent));
+      
+      VerticalPanel rightPanel = new VerticalPanel();
+      rightPanel.add(new HTMLPanel(rightContent));
+      
+      RootPanel.get("leftPanel").add(leftPanel);
+      RootPanel.get("centerPanel").add(centerPanel);
+      RootPanel.get("rightPanel").add(rightPanel);
+   }
+   
+   /**
+    * 
+    *
+    */
+   private void performFlexibleGridLayout()
+   {
+      FlexTable flexTable = new FlexTable();
+      
+      flexTable.setWidget(0, 0, new HTMLPanel(leftContent));
+      flexTable.setWidget(0, 1, new HTMLPanel(leftContent));
+      flexTable.setWidget(1, 0, new HTMLPanel(leftContent));
+      flexTable.setWidget(1, 1, new HTMLPanel(rightContent));
+      
+      RootPanel.get("flexGrid").add(flexTable);
+   }
+   
+   /**
+    * 
+    *
+    */
+   private void createPortletButtons()
+   {
+      Button cmsPortletButton = new Button("cmsPortlet");
+      Button jspPortletButton = new Button("jspPortlet");
+      Button weatherPortletButton = new Button("weatherPortlet");
+      
+      ClickListener listener = new ClickListener()
+      {
+         public void onClick(Widget sender)
+         {
+            Button button = (Button)sender;
+            if (button.getText().equals("cmsPortlet"))
+            {
+               refreshFlexibleGrid("cmsPortlet.html");
+            }
+            else if (button.getText().equals("jspPortlet"))
+            {
+               refreshFlexibleGrid("jspPortlet.html");
+            }
+            else if (button.getText().equals("weatherPortlet"))
+            {
+               refreshFlexibleGrid("weatherPortlet.html");
+            }
+         } 
+      };
+      
+      cmsPortletButton.addClickListener(listener);
+      jspPortletButton.addClickListener(listener);
+      weatherPortletButton.addClickListener(listener);
+      
+      
+      RootPanel.get("cmsPortlet").add(cmsPortletButton);
+      RootPanel.get("jspPortlet").add(jspPortletButton);
+      RootPanel.get("weatherPortlet").add(weatherPortletButton);
+   }
+   
+   /**
+    * 
+    *
+    */
+   private void refreshFlexibleGrid(String portletId)
+   {
+      PortletServiceAsync portletService = (PortletServiceAsync)GWT.create(PortletService.class);
+      
+      ((ServiceDefTarget)portletService).setServiceEntryPoint(GWT.getModuleBaseURL()+"/portletService");
+      
+      AsyncCallback callback = new AsyncCallback()
+      {
+         public void onSuccess(Object result)
+         {
+            String portletContent = (String)result;
+                        
+            FlexTable flexTable = new FlexTable();
+            flexTable.setWidget(0, 0, new HTMLPanel(portletContent));
+            flexTable.setWidget(1, 1, new HTMLPanel(portletContent));
+            
+            RootPanel.get("flexGrid").clear();
+            RootPanel.get("flexGrid").add(flexTable);
+         }
+         
+         public void onFailure(Throwable caught)
+         {
+         }
+      };
+      
+      portletService.getPortlet(portletId, callback);
+   }   
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortletService.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortletService.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortletService.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,66 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.ajax.client;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+
+import org.jboss.portal.presentation.ajax.client.protocol.Page;
+
+/**
+ * A Protototype RPC service
+ * 
+ * @author soshah
+ *
+ */
+public interface PortletService extends RemoteService
+{
+   /**
+    * 
+    * @param portletId
+    * @return
+    */
+   public String getPortlet(String portletId);
+   
+   /**
+    * 
+    * @param pageId
+    * @return
+    */
+   public Page getPage(String pageId);
+   
+   /**
+    * 
+    * @param window
+    * @param state
+    * @return
+    */
+   public Page setState(String window, String newState);
+   
+   /**
+    * 
+    * @param window
+    * @param newMode
+    * @return
+    */
+   public Page setMode(String window, String newMode);   
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortletServiceAsync.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortletServiceAsync.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortletServiceAsync.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,63 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.ajax.client;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+/**
+ * A Prototype RPC Service
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public interface PortletServiceAsync
+{
+   /**
+    * 
+    * @param portletId
+    * @return
+    */
+   public void getPortlet(String portletId, AsyncCallback callback);
+   
+   /**
+    * 
+    * @param pageId
+    * @param callback
+    */
+   public void getPage(String pageId, AsyncCallback callback);
+   
+   /**
+    * 
+    * @param window
+    * @param callback
+    */
+   public void setState(String window, String newState, AsyncCallback callback);
+   
+   /**
+    * 
+    * @param window
+    * @param newMode
+    * @return
+    */
+   public void setMode(String window, String newMode, AsyncCallback callback);   
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortletWindowPanel.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortletWindowPanel.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/PortletWindowPanel.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,47 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.ajax.client;
+
+import com.google.gwt.user.client.ui.HTMLPanel;
+import com.google.gwt.user.client.Event;
+
+public class PortletWindowPanel extends HTMLPanel
+{
+   /**
+    * 
+    * @param html
+    */
+   public PortletWindowPanel(String html)
+   {
+      super(html);
+   }
+   
+   public void onBrowserEvent(Event event)
+   {
+      super.onBrowserEvent(event);
+      
+      System.out.println("-------------------------------");
+      System.out.println(event);
+      System.out.println("-------------------------------");
+   }
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/layout/LayoutManager.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/layout/LayoutManager.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/layout/LayoutManager.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,164 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.ajax.client.layout;
+
+import java.util.List;
+
+import com.google.gwt.user.client.ui.Widget;
+
+import net.mygwt.ui.client.widget.Viewport;
+import net.mygwt.ui.client.widget.WidgetContainer;
+import net.mygwt.ui.client.widget.layout.BorderLayout;
+import net.mygwt.ui.client.widget.layout.BorderLayoutData;
+import net.mygwt.ui.client.widget.layout.FlowLayout;
+import net.mygwt.ui.client.Style;
+
+import org.jboss.portal.presentation.ajax.client.widget.PortletWindow;
+
+/**
+ * This layout manager provides a Flexible Grid for laying out the UI components (which would be Portlet Windows)
+ * inside a flexible coordinates based Grid
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public class LayoutManager
+{
+   /**
+    * 
+    */
+   private static Viewport viewport = null;
+   
+   /**
+    * 
+    */
+   private static WidgetContainer north = null;
+   
+   /**
+    * 
+    */
+   private static WidgetContainer west = null;
+   
+   /**
+    * 
+    */
+   private static WidgetContainer center = null;
+   
+   
+   /**
+    * 
+    */
+   static
+   {
+      LayoutManager.viewport = new Viewport();
+      
+      //Layout for the viewport
+      BorderLayout pageLayout = new BorderLayout();
+            
+      //Layout for the north region (Header/Navigation related content produced by the portal are laid out here)
+      FlowLayout northLayout = new FlowLayout();
+      
+      //Setup the layout of the root container of the page
+      LayoutManager.viewport.setLayout(pageLayout);
+      
+      //Setup the north region of the page
+      LayoutManager.north = new WidgetContainer();
+      LayoutManager.north.setLayout(northLayout);
+      float northSize = LayoutManager.viewport.getOffsetHeight() * ((float)0.05);
+      BorderLayoutData northData = new BorderLayoutData(Style.NORTH, northSize);
+      northData.resizeable = true;
+      LayoutManager.viewport.add(LayoutManager.north, northData);
+   }
+   
+   /**
+    * 
+    * @param displayWindows
+    */
+   public static void doLayout(List displayWindows)
+   {      
+      LayoutManager.setUpPortletRegions();
+            
+      int column = 0;
+      for(int i=0; i<displayWindows.size(); i++)
+      {
+         PortletWindow portletWindow = (PortletWindow)displayWindows.get(i);         
+         Widget window = portletWindow.create();
+         //Add this window to the Page
+         if(column == 0 && displayWindows.size()>1)
+         {
+            LayoutManager.west.add(window);
+            column ++;
+         }
+         else
+         {
+            LayoutManager.center.add(window);               
+            column = 0;
+         }
+      }            
+      LayoutManager.viewport.layout(true);
+   }
+   
+   /**
+    * 
+    *
+    */
+   private static void setUpPortletRegions()
+   {
+      if(LayoutManager.west != null)
+      {
+         LayoutManager.viewport.remove(LayoutManager.west);
+      }
+      if(LayoutManager.center != null)
+      {
+         LayoutManager.viewport.remove(LayoutManager.center);
+      }
+      
+      //Re-add these two regions
+      //Layout for the west region (Portlet Windows are laid out here)
+      FlowLayout westLayout = new FlowLayout();
+      westLayout.spacing = 5;
+      westLayout.margin = 5;
+      
+      //Layout for the center region (Portlet Windows are laid out here)
+      FlowLayout centerLayout = new FlowLayout();
+      centerLayout.spacing = 5;
+      centerLayout.margin = 5;
+      
+      //Setup the west region of the page
+      LayoutManager.west = new WidgetContainer();
+      LayoutManager.west.setScrollEnabled(true);
+      LayoutManager.west.setLayout(westLayout);      
+      float westSize = LayoutManager.viewport.getOffsetWidth() * ((float)0.2);  
+      BorderLayoutData westData = new BorderLayoutData(Style.WEST, westSize);
+      westData.resizeable = true;
+      LayoutManager.viewport.add(LayoutManager.west, westData);
+      
+      //Setup the center region of the page
+      LayoutManager.center = new WidgetContainer();
+      LayoutManager.center.setScrollEnabled(true);
+      LayoutManager.center.setLayout(centerLayout);
+      BorderLayoutData centerData = new BorderLayoutData(Style.CENTER);
+      centerData.resizeable = true;
+      LayoutManager.viewport.add(LayoutManager.center, centerData);
+   }
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/protocol/Page.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/protocol/Page.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/protocol/Page.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,73 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.ajax.client.protocol;
+
+import com.google.gwt.user.client.rpc.IsSerializable;
+
+/**
+ * Represents the concept of a Portal Page on the client-side Ajax agent
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public class Page implements IsSerializable
+{
+   private String name = null;
+   private Window[] windows = null;
+   
+   /**
+    * 
+    * @return
+    */
+   public String getName()
+   {
+      return name;
+   }
+   
+   /**
+    * 
+    * @param name
+    */
+   public void setName(String name)
+   {
+      this.name = name;
+   }
+   
+   /**
+    * 
+    * @return
+    */
+   public Window[] getWindows()
+   {
+      return windows;
+   }
+   
+   /**
+    * 
+    * @param windows
+    */
+   public void setWindows(Window[] windows)
+   {
+      this.windows = windows;
+   }   
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/protocol/Window.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/protocol/Window.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/protocol/Window.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,136 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.ajax.client.protocol;
+
+import com.google.gwt.user.client.rpc.IsSerializable;
+
+/**
+ * Represents the concept of a Portal Window on the client-side Ajax agent
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public class Window implements IsSerializable
+{
+   public static final String NORMAL = "NORMAL";
+   public static final String MAXIMIZED = "MAXIMIZED";
+   public static final String MINIMIZED = "MINIMIZED";
+   public static final String EDIT = "EDIT";
+   public static final String VIEW = "VIEW";
+   
+   private String name = null;
+   private String content = null;
+   private String mode = VIEW;
+   private String state = NORMAL;
+   private boolean isVisible = true;
+   
+   /**
+    * 
+    * @return
+    */
+   public String getContent()
+   {
+      return content;
+   }
+   
+   /**
+    * 
+    * @param content
+    */
+   public void setContent(String content)
+   {
+      this.content = content;
+   }
+   
+   /**
+    * 
+    * @return
+    */
+   public boolean isVisible()
+   {
+      return isVisible;
+   }
+   
+   /**
+    * 
+    * @param isVisible
+    */
+   public void setVisible(boolean isVisible)
+   {
+      this.isVisible = isVisible;
+   }
+   
+   /**
+    * 
+    * @return
+    */
+   public String getMode()
+   {
+      return mode;
+   }
+   
+   /**
+    * 
+    * @param mode
+    */
+   public void setMode(String mode)
+   {
+      this.mode = mode;
+   }
+   
+   /**
+    * 
+    * @return
+    */
+   public String getName()
+   {
+      return name;
+   }
+   
+   /**
+    * 
+    * @param name
+    */
+   public void setName(String name)
+   {
+      this.name = name;
+   }
+   
+   /**
+    * 
+    * @return
+    */
+   public String getState()
+   {
+      return state;
+   }
+   
+   /**
+    * 
+    * @param state
+    */
+   public void setState(String state)
+   {
+      this.state = state;
+   }
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/service/PortalRPC.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/service/PortalRPC.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/service/PortalRPC.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,48 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.ajax.client.service;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+
+import org.jboss.portal.presentation.ajax.client.protocol.Page;
+
+/**
+ * RPC service used for Asynchronous communication between the client-side agent and the Portal Server
+ * 
+ * @author soshah
+ *
+ */
+public interface PortalRPC extends RemoteService
+{   
+   /**
+    * Loads the initial Portal Page at the start of a Portal session
+    * 
+    * @return The Initial Portal Page
+    */
+   public Page loadPortal();
+   
+   /**
+    * @return The Page of the Portal that should be currently displayed
+    */
+   public Page getCurrentPage();
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/service/PortalRPCAsync.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/service/PortalRPCAsync.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/service/PortalRPCAsync.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,44 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.ajax.client.service;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+/**
+ * RPC service used for Asynchronous communication between the client-side agent and the Portal Server
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public interface PortalRPCAsync
+{   
+   /**
+    * Loads the initial Portal Page at the start of a Portal session
+    */
+   public void loadPortal(AsyncCallback callback);
+   
+   /**
+    * Loads the Page of the Portal that should be currently displayed
+    */
+   public void getCurrentPage(AsyncCallback callback);
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/widget/PortletWindow.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/widget/PortletWindow.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/ajax/client/widget/PortletWindow.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,383 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.ajax.client.widget;
+
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.ClickListener;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.HTTPRequest;
+import com.google.gwt.user.client.ResponseTextHandler;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.user.client.ui.Panel;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.ClickListener;
+import com.google.gwt.user.client.ui.FlexTable;
+
+import net.mygwt.ui.client.widget.ContentPanel;
+import net.mygwt.ui.client.Style;
+import net.mygwt.ui.client.widget.IconButton;
+import net.mygwt.ui.client.widget.Info;
+import net.mygwt.ui.client.event.Listener;
+import net.mygwt.ui.client.event.Listener;
+import net.mygwt.ui.client.event.BaseEvent;
+
+import org.jboss.portal.presentation.ajax.client.protocol.Window;
+
+/**
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public class PortletWindow
+{
+   /**
+    * 
+    */
+   private Window window = null;
+   
+   /**
+    * 
+    *
+    */
+   public PortletWindow(Window window)
+   {  
+      this.window = window;
+   }
+   
+   /**
+    * 
+    * @return
+    */
+   public ContentPanel create()
+   {
+      ContentPanel portletWindow = new ContentPanel(Style.HEADER);
+      String windowName = this.window.getName();
+      String content = this.window.getContent();
+      portletWindow.setId(windowName);
+      HTML windowContent = new HTML(content);                                                              
+      
+      
+      //Setup listeners
+      //Event Listener for the decoration components like
+      //Normal, Maximized, Minimized
+      Listener listener = new Listener()
+      {
+         public void handleEvent(BaseEvent event)
+         {   
+            IconButton cour = (IconButton)event.widget;
+            String id = cour.getId();            
+            String windowName = id.substring(0, id.indexOf(':'));
+            String action = id.substring(id.indexOf(':')+1);
+            if(action.equals("restore"))
+            {
+               //handleWindowStateChanged(windowName, Window.NORMAL);
+               Info.show("Normal", "Loading Normal Mode....", "Loading Normal Mode....");
+            }
+            else if(action.equals("minimize"))
+            {
+               //handleWindowStateChanged(windowName, Window.MINIMIZED);
+               Info.show("Minimize", "Loading Minimize Mode....", "Loading Minimize Mode....");
+            }
+            else if(action.equals("maximize"))
+            {
+               //handleWindowStateChanged(windowName, Window.MAXIMIZED);
+               Info.show("Maximize", "Loading Maximize Mode....", "Loading Maximize Mode....");
+            }
+            else if(action.equals("save"))
+            {
+               //handleWindowModeChanged(windowName, Window.EDIT);
+               Info.show("Save", "Loading Save Mode....", "Loading Save Mode....");
+            }
+            else if(action.equals("help"))
+            {
+               //handleWindowModeChanged(windowName, Window.EDIT);
+               Info.show("Help", "Loading Help Mode....", "Loading Help Mode....");
+            }
+         } 
+      };
+      IconButton save = new IconButton("my-tool-save");
+      save.setId(windowName+":save");
+      save.setToolTip("Edit");
+      IconButton help = new IconButton("my-tool-help");
+      help.setId(windowName+":help");
+      help.setToolTip("Help");
+      IconButton restore = new IconButton("my-tool-restore");
+      restore.setId(windowName+":restore");
+      restore.setToolTip("Normal");
+      IconButton minimize = new IconButton("my-tool-minimize");
+      minimize.setId(windowName+":minimize");
+      minimize.setToolTip("Minimize");
+      IconButton maximize = new IconButton("my-tool-maximize");
+      maximize.setId(windowName+":maximize");
+      maximize.setToolTip("Maximize");
+      portletWindow.addButton(save, listener);
+      portletWindow.addButton(help, listener);
+      portletWindow.addButton(restore, listener);
+      portletWindow.addButton(minimize, listener);
+      portletWindow.addButton(maximize, listener);
+      
+      //Event Listener for actions perfomed inside the portlet window content
+      //itself. Used for performing Partial Refresh of a Portal Page
+      /*ClickListener contentListener = new ClickListener()
+      {
+         public void onClick(Widget sender)
+         {
+            Event event = DOM.eventGetCurrentEvent();
+            Element target = DOM.eventGetTarget(event);
+                        
+            if(target.toString().toUpperCase().trim().indexOf("</A>") != -1)
+            {               
+               String link = DOM.getElementAttribute(target, "HREF");
+               
+               //A link inside the portlet window was clicked
+               //Load its content asynchronously inside this window
+               boolean isPartialRefreshAllowed = isPartialRefreshAllowed(link);               
+               if(isPartialRefreshAllowed)
+               {
+                  DOM.eventPreventDefault(event);
+                  handlePartialRefreshLink(link, sender);
+               }
+            }
+            else if(target.toString().toUpperCase().trim().indexOf("INPUT") != -1 &&
+                    target.toString().toUpperCase().trim().indexOf("SUBMIT") != -1
+            )
+            {               
+               Element currentForm = DOM.getParent(target);
+               String enctype = DOM.getElementAttribute(currentForm, "enctype");
+               String action = DOM.getElementAttribute(currentForm, "action");
+               boolean isPartialRefreshAllowed = isPartialRefreshAllowed(action);
+               if((isPartialRefreshAllowed) && (enctype == null || !enctype.equals("multipart/form-data")))
+               {
+                  DOM.eventPreventDefault(event);
+                  
+                  //Call a native javascript function here                  
+                  String method = DOM.getElementAttribute(currentForm, "method");                  
+                  String serializedForm = serializeForm(currentForm);   
+                  
+                  handlePartialRefreshForm(action, method, serializedForm, sender);
+               }
+            }
+         } 
+      };
+      windowContent.addClickListener(contentListener);*/
+      
+      //Add the content
+      portletWindow.add(windowContent);
+      
+      return portletWindow;
+   }   
+   //-------------------------------------------------------------------------------------------------------------------------------------------------------------
+   /**
+    * 
+    * @param window
+    * @param newState
+    */
+   /*private void handleWindowStateChanged(String window, String newState)
+   {
+      PortletServiceAsync portletService = (PortletServiceAsync)GWT.create(PortletService.class);      
+      ((ServiceDefTarget)portletService).setServiceEntryPoint(GWT.getModuleBaseURL()+"/portalrpc");
+      
+      AsyncCallback callback = new AsyncCallback()
+      {
+         public void onSuccess(Object result)
+         {  
+            Page portalPage = (Page)result;
+            displayPortalPage(portalPage);
+         }
+         
+         public void onFailure(Throwable caught)
+         {
+         }
+      };
+      
+      portletService.setState(window, newState, callback);
+   }*/
+   
+   /**
+    * 
+    * @param window
+    * @param newState
+    */
+   /*private void handleWindowModeChanged(String window, String newMode)
+   {
+      PortletServiceAsync portletService = (PortletServiceAsync)GWT.create(PortletService.class);      
+      ((ServiceDefTarget)portletService).setServiceEntryPoint(GWT.getModuleBaseURL()+"/portalrpc");
+      
+      AsyncCallback callback = new AsyncCallback()
+      {
+         public void onSuccess(Object result)
+         {  
+            Page portalPage = (Page)result;
+            displayPortalPage(portalPage);
+         }
+         
+         public void onFailure(Throwable caught)
+         {
+         }
+      };
+      
+      portletService.setMode(window, newMode, callback);
+   }*/
+   
+   /**
+    * 
+    * @param url
+    * @param portletWindow
+    */
+   /*private void handlePartialRefreshLink(String url, Widget windowContent)
+   {
+      HTTPRequest.asyncGet(url, new ResponseTextHandlerImpl(windowContent));
+   }*/
+   
+   /**
+    * 
+    * @param url
+    * @param portletWindow
+    */
+   /*private void handlePartialRefreshForm(String url, String method, String postData, Widget windowContent)
+   {                  
+      if(method.equalsIgnoreCase("post"))
+      {
+         HTTPRequest.asyncPost(url, postData, new ResponseTextHandlerImpl(windowContent));
+      }
+      else if(method.equalsIgnoreCase("get"))
+      {
+         if(postData != null && postData.trim().length() > 0)
+         {
+            url = url + "?" + postData;
+         }
+         HTTPRequest.asyncGet(url, new ResponseTextHandlerImpl(windowContent));
+      }
+   }*/
+   
+   /**
+    * 
+    * @author soshah
+    *
+    */
+   /*private class ResponseTextHandlerImpl implements ResponseTextHandler
+   {
+      private Widget windowContent = null;
+      
+      public ResponseTextHandlerImpl(Widget windowContent)
+      {
+         this.windowContent = windowContent;
+      }      
+      public void onCompletion(String responseText)
+      {
+         HTML html = new HTML(responseText);          
+         Panel window =  (Panel)this.windowContent.getParent();
+         this.windowContent.removeFromParent();
+         window.add(html);
+      } 
+   }*/
+   
+   /**
+    * 
+    * @param url
+    * @return
+    */
+   /*private boolean isPartialRefreshAllowed(String url)
+   {      
+      String basePortalURL = GWT.getModuleBaseURL();
+      String portalContext = "org.jboss.portal.uiserver.Portal"; //This is hard coded for now, but must be populated from the Portal deployment environment
+      //If Portal is installed at Root context, this value will be an empty string
+      
+      if(url.startsWith(basePortalURL))
+      {
+         //This is an Absolute URL, but it points back to
+         //the Portal
+         //An Async Page Refresh call should be allowed in this case
+         return true;
+      }
+      
+      if(url.startsWith("http://"))
+      {
+         //This is an Absolute URL and does not point back
+         //to the Portal
+         //Async Page Refresh call should not be allowed
+         return false;
+      }
+      else
+      {
+         //This is a relative URL. 
+         
+         //Make sure it points back to the Portal for an Async Page Refresh        
+         //If it points to some other resource like another third-party web application etc, the response
+         //has nothing to do with Portal 
+         //(unless ofcourse the client side processor of the Portal, wants to
+         //take this response and aggregate this inside the current Portal Page and Window being displayed. This is an exceptional usecase
+         //and not desired behavior for every scenario from end user standpoint)
+         //As standard behavior, Async Page Refresh to be done, only when Portlet Markup is sending a request back to the Portal         
+         if(url.startsWith("/"))
+         {
+            if(!portalContext.equals(""))
+            {
+               String urlContext = null;
+               int index = url.indexOf('/', 1);
+               if(index != -1)
+               {
+                  urlContext = url.substring(1, index);
+               }
+               else
+               {
+                  urlContext = url.substring(1);
+               }
+               
+               if(!portalContext.equals(urlContext))
+               { 
+                  //This request is not being sent to the Portal. It is being sent to some other web application
+                  return false;
+               }
+            }
+            else
+            {
+               //If Portal is running on root context, there is no way to tell from client side, if this request is actually
+               //to be sent to the Portal or some other web application. Hence, in the interest of functional safety/correctness
+               //no Async Page Refresh here
+               //If Portal is running on Root context, Partial Refresh will happen only for pure relative links
+               return false;
+            }
+         }
+         
+         //If I get here, Async Page Refresh through the Portal should be allowed
+         return true;
+      }
+   }*/
+   
+   /**
+    * 
+    * @param currentForm
+    * @return
+    */
+   public native String serializeForm(Element currentForm) 
+   /*-{      
+      var formData = $wnd.Form.serialize(currentForm);
+      return formData;
+   }-*/;
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/controller/UIController.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/controller/UIController.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/controller/UIController.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,252 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.controller;
+
+import java.util.StringTokenizer;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.jboss.portal.presentation.RequestContext;
+import org.jboss.portal.presentation.server.ProcessorRequest;
+import org.jboss.portal.presentation.server.ProcessorResponse;
+import org.jboss.portal.presentation.server.PresentationServer;
+import org.jboss.portal.presentation.action.server.ServerAction;
+import org.jboss.portal.presentation.action.server.ServerResponse;
+import org.jboss.portal.presentation.action.server.LinkActivation;
+import org.jboss.portal.presentation.action.server.GetActivation;
+import org.jboss.portal.presentation.action.server.PostActivation;
+import org.jboss.portal.presentation.action.server.ViewUIObjectAction;
+import org.jboss.portal.presentation.model.UIPortal;
+import org.jboss.portal.presentation.model.UIObject;
+import org.jboss.portal.presentation.model.UIPage;
+import org.jboss.portal.presentation.model.UIWindow;
+import org.jboss.portal.presentation.model.state.ObjectState;
+
+import org.jboss.portal.server.RequestController;
+import org.jboss.portal.server.ServerException;
+import org.jboss.portal.server.ServerInvocation;
+import org.jboss.portal.server.ServerInvocationContext;
+
+
+/**
+ * The UIServer is responsible for generating the output that is sent back to the client based on the Portal state of a particular Portal Request
+ * 
+ * The UIServer provides various UI level services like Page Aggregation, Page Layout, Web 2.0 client interactions etc.
+ * 
+ * Typically the Core component of the Portal delegates all UI specific functions to this component
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public class UIController implements RequestController
+{
+   /**
+    * 
+    */
+   private PresentationServer presentationServer = null;
+      
+   
+   /**
+    * 
+    *
+    */
+   public UIController()
+   {      
+   }
+      
+   
+   /**
+    * handle is the entry point for handling an incoming Portal request. The request is handed over
+    * from the Http Layer via the main Portal Servlet
+    *
+    */  
+   public void handle(ServerInvocation invocation) throws ServerException
+   { 
+      try
+      { 
+         //Make a request to the Processor
+         RequestContext requestContext = null; //Just use null until proper implementation is provided
+         ServerAction serverAction = this.getServerAction(requestContext,invocation);
+         ProcessorRequest processorRequest = new ProcessorRequest(serverAction, invocation);         
+         ProcessorResponse processorResponse = this.presentationServer.getProcessor().process(requestContext,
+         processorRequest);
+                  
+         //Process the response from the Processor
+         ServerResponse serverResponse = processorResponse.getResponse();
+      }
+      catch(Exception e)
+      {
+         throw new ServerException(e);
+      }
+   }   
+   
+   /**
+    * 
+    *
+    */
+   public void start()
+   {
+      
+   }
+   
+   /**
+    * 
+    *
+    */
+   public void stop()
+   {
+      
+   }
+   //-----------------------------------------------------------------------------------------------------------------------------------------------------------
+   /**
+    * 
+    */
+   public PresentationServer getPresentationServer()
+   {
+      return presentationServer;
+   }
+
+   /**
+    * 
+    * @param presentationServer
+    */
+   public void setPresentationServer(PresentationServer presentationServer)
+   {
+      this.presentationServer = presentationServer;
+   }  
+   //--------------------------------------------------------------------------------------------------------------------------------------------------------------
+   /**
+    * 
+    */
+   private ServerAction getServerAction(RequestContext requestContext,ServerInvocation invocation)
+   {
+      ServerAction serverAction = null;
+      
+      ServerInvocationContext invocationContext = invocation.getServerContext();
+      HttpServletRequest request = invocationContext.getClientRequest();
+      
+      String portalRequestPath = invocation.getServerContext().getPortalRequestPath(); 
+      if(portalRequestPath == null || portalRequestPath.equals("") || portalRequestPath.equals("/") || portalRequestPath.equals("/index.html"))
+      {
+         portalRequestPath = "/default/default";
+      }
+      
+      UIPortal targetPortal = this.getTargetPortal(requestContext,portalRequestPath);
+      UIObject targetPortalObject = this.getTargetPortalObject(requestContext,portalRequestPath);
+      
+      if(targetPortalObject instanceof UIPage)
+      {
+         serverAction = new ViewUIObjectAction(targetPortalObject.getId());
+      }
+      else if(targetPortalObject instanceof UIWindow)
+      {
+         if(request.getMethod().equals("GET"))
+         {
+            GetActivation get = new GetActivation();
+            get.setUrl(request.getRequestURL().toString());
+            get.setContentType(invocationContext.getMediaType());
+            get.setQueryParameters(invocationContext.getQueryParameterMap());
+            get.setPortal(targetPortal);
+            get.setTarget(targetPortalObject);
+            serverAction = get;
+         }
+         else if(request.getMethod().equals("POST"))
+         {
+            PostActivation post = new PostActivation();
+            post.setUrl(request.getRequestURL().toString());
+            post.setContentType(invocationContext.getMediaType());
+            post.setQueryParameters(invocationContext.getQueryParameterMap());
+            post.setBodyParameters(invocationContext.getBodyParameterMap());
+            post.setPortal(targetPortal);
+            post.setTarget(targetPortalObject);
+            serverAction = post;
+         }
+      }
+      
+      return serverAction;
+   }
+   
+   /**
+    * 
+    * @param portalRequestPath
+    * @return
+    */
+   private UIPortal getTargetPortal(RequestContext requestContext,String portalRequestPath)
+   {
+      UIPortal targetPortal = null;
+      
+      //Parse the portalRequestPath and find the targetted Portal           
+      StringTokenizer st = new StringTokenizer(portalRequestPath, "/");
+      StringBuffer buffer = new StringBuffer("/");
+      while(st.hasMoreTokens())
+      {
+         String token = st.nextToken();         
+         buffer.append(token);
+         String id = buffer.toString();
+         ObjectState objectState = this.presentationServer.getModelLoader().loadState(id);
+         if(objectState != null && objectState.getType() == UIPortal.class)
+         {
+            targetPortal = requestContext.getUIContext().getObject(id, UIPortal.class);
+            break;
+         }
+         buffer.append("/");
+      }
+      
+      return targetPortal;
+   }
+   
+   /**
+    * 
+    * @param portalRequestPath
+    * @return
+    */
+   private UIObject getTargetPortalObject(RequestContext requestContext,String portalRequestPath)
+   {
+      UIObject targetPortalObject = null;
+      
+      //Parse the portalRequestPath and find the targetted Portal Object (Page or Window)           
+      StringTokenizer st = new StringTokenizer(portalRequestPath, "/");
+      StringBuffer buffer = new StringBuffer("/");
+      while(st.hasMoreTokens())
+      {
+         String token = st.nextToken();         
+         buffer.append(token);
+         String id = buffer.toString();
+         ObjectState objectState = this.presentationServer.getModelLoader().loadState(id);
+         if(objectState != null)
+         {
+            if(objectState.getType() == UIPage.class)
+            {
+               targetPortalObject = requestContext.getUIContext().getObject(id, UIPage.class);
+            }
+            else if(objectState.getType() == UIWindow.class)
+            {
+               targetPortalObject = requestContext.getUIContext().getObject(id, UIWindow.class);
+            }
+         }
+         buffer.append("/");
+      }
+      
+      return targetPortalObject;
+   }
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/entry/EntryPoint.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/entry/EntryPoint.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/entry/EntryPoint.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,61 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.entry;
+
+import org.jboss.portal.server.RequestControllerFactory;
+import org.jboss.portal.server.Server;
+import org.jboss.portal.common.invocation.InterceptorStackFactory;
+
+/**
+ * A Utility Service used by different Portal Server Entry Points
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public interface EntryPoint
+{
+   /**
+    * 
+    * @return
+    */
+   public Server getPortalServer();
+   
+   /**
+    * 
+    * @return
+    */
+   public RequestControllerFactory getControllerFactory();
+   
+   /**
+    * 
+    * @return
+    */
+   public InterceptorStackFactory getInterceptorStackFactory();
+   
+   /**
+    * 
+    * @param contentType
+    * @return
+    */
+   public String retrieveMediaType(String contentType);
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/entry/GWTClientFilter.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/entry/GWTClientFilter.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/entry/GWTClientFilter.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,154 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.entry;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ByteArrayOutputStream;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * This filter is activated or deactivated depending on whether the Portal needs to runs in Ajax mode or Classic Html mode
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public class GWTClientFilter implements Filter
+{
+   /**
+    * 
+    */
+   public void init(FilterConfig arg0) throws ServletException
+   {  
+   }
+   
+   /**
+    * 
+    */
+   public void destroy()
+   {  
+   }
+
+   /**
+    * 
+    */
+   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
+   { 
+      HttpServletRequest request = (HttpServletRequest)servletRequest;
+      HttpServletResponse response = (HttpServletResponse)servletResponse;
+      String contextPath = request.getContextPath();
+      
+      //Extract the resource that is being accessed
+      String resource = request.getRequestURI().replaceFirst(contextPath, "");
+      while(resource.startsWith("/"))
+      {
+         if(resource.length() > 1)
+         {
+            resource = resource.substring(1);
+         }
+         else
+         {
+            resource = "";
+         }
+      }
+      
+      if(resource == null || resource.trim().length() == 0)
+      {
+         response.sendRedirect("index.html");
+         return;
+      }
+      
+      //Now make sure the resource requested is a GWT resource
+      if(   resource.equals("index.html") ||
+            resource.equals("portal.css") ||
+            resource.equals("mygwt-all.css") ||
+            resource.equals("mygwt-all-gray.css") ||
+            resource.equals("gwt.js") ||
+            resource.equals("prototype.js") ||
+            resource.contains(".cache.") ||
+            resource.contains(".nocache.") ||
+            resource.contains(".gwt.rpc") ||
+            resource.contains("images/default") ||
+            resource.contains("images/gray")
+      )
+      {
+         byte[] gwtResource = this.readContent(resource);
+         response.getOutputStream().write(gwtResource);
+         response.getOutputStream().flush();
+         return;
+      }
+   }
+   
+   /**
+    * 
+    * @param path
+    * @return
+    */
+   private byte[] readContent(String path)
+   {
+      byte[] content = null;
+        
+      InputStream is = null;
+      ByteArrayOutputStream bos = null;
+      try
+      {
+         bos = new ByteArrayOutputStream();
+         is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
+         int bytesRead = 0;
+         byte[] data = new byte[1024];
+         while((bytesRead=is.read(data)) != -1)
+         {
+            byte[] cour = new byte[bytesRead];
+            System.arraycopy(data, 0, cour, 0, bytesRead);
+            bos.write(cour);
+            bos.flush();
+         }         
+      }
+      catch(Exception e)
+      {
+         throw new RuntimeException(e);
+      }
+      finally
+      {
+         if(is != null)
+         {
+            try{is.close();}catch(Exception e){}
+         }
+         if(bos != null)
+         {
+            content = bos.toByteArray();
+            try{bos.close();}catch(Exception e){}
+         }
+      }
+      
+      return content;
+   }
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/ajax/entry/PortalEntryPoint.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/ajax/entry/PortalEntryPoint.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/ajax/entry/PortalEntryPoint.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,222 @@
+package org.jboss.portal.presentation.impl.ajax.entry;
+
+
+import java.util.Map;
+import java.util.List;
+import java.util.HashMap;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import javax.servlet.ServletException;
+import javax.servlet.UnavailableException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.log4j.Logger;
+import org.jboss.mx.util.MBeanProxy;
+import org.jboss.mx.util.MBeanServerLocator;
+
+import org.jboss.portal.common.invocation.InterceptorStackFactory;
+import org.jboss.portal.server.RequestControllerFactory;
+import org.jboss.portal.server.Server;
+import org.jboss.portal.server.ServerInvocationContext;
+import org.jboss.portal.server.impl.ServerInvocationContextImpl;
+import org.jboss.portal.server.request.URLContext;
+import org.jboss.portal.server.ServerRequest;
+import org.jboss.portal.server.ServerResponse;
+import org.jboss.portal.server.ServerInvocation;
+import org.jboss.portal.server.RequestController;
+import org.jboss.portal.server.RequestControllerDispatcher;
+
+import org.jboss.portal.presentation.ajax.client.service.PortalRPC;
+import org.jboss.portal.presentation.ajax.client.protocol.Page;
+import org.jboss.portal.presentation.ajax.client.protocol.Window;
+import org.jboss.portal.presentation.server.ProcessorResponse;
+import org.jboss.portal.presentation.entry.EntryPoint;
+
+import com.google.gwt.user.client.rpc.SerializationException;
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+/**
+ * This serves as the Portal Entry Point for AJAX (Asynchronous) RPC calls being made by the
+ * client-side Ajax agent of the Presentation Framework
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ * 
+ */
+public class PortalEntryPoint extends RemoteServiceServlet implements 
+PortalRPC
+{
+   /** The logger. */
+   private Logger log = Logger.getLogger(getClass());
+
+   /**
+    * 
+    */
+   private EntryPoint entryPoint = null;
+
+   /** Configure the as default servlet. */
+   public void init() throws ServletException
+   {
+      try
+      {
+         MBeanServer mbeanServer = MBeanServerLocator.locateJBoss();
+         this.entryPoint = (EntryPoint) MBeanProxy.get(EntryPoint.class, new ObjectName(
+               this.getInitParameter("entryPointServiceName")),
+               mbeanServer);
+      }
+      catch (Exception e)
+      {
+         this.entryPoint = null;
+         String msg = "Portal Entry Point could not be created";
+         log.error(msg, e);
+         throw new UnavailableException(msg);
+      }
+   }
+   
+   /**
+    * 
+    */
+   public String processCall(String payload) throws SerializationException
+   {
+      HttpServletRequest request = this.getThreadLocalRequest();
+            
+      //Perform the remote procedure call
+      String returnVal =  super.processCall(payload);
+      
+      //Perform any post-processing after calling the actual remote method that will perform
+      //the functionality for this particular remote procedure call      
+      
+      return returnVal;
+   }
+   // -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+   /**
+    * Loads the initial Portal Page at the start of a Portal session
+    * 
+    * @return The Initial Portal Page
+    */
+   public Page loadPortal()
+   {
+      try
+      {
+         Page display = null;
+         HttpServletRequest request = this.getThreadLocalRequest();
+         this.callPortalServer();
+         display = this.getDisplay((ProcessorResponse)request.getAttribute("processorResponse"));
+         return display;
+      }
+      catch(Exception e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   /**
+    * @return The Page of the Portal that should be currently displayed
+    */
+   public Page getCurrentPage()
+   {
+      Page currentPage = null;
+
+      HttpServletRequest request = this.getThreadLocalRequest();
+
+      ProcessorResponse processorResponse = (ProcessorResponse) request.getSession().getAttribute("processorResponse");
+      
+      currentPage = this.getDisplay(processorResponse);
+
+      return currentPage;
+   } 
+   //-------------------------------------------------------------------------------------------------------------------------------------------------------------------
+   /**
+    * 
+    * @param processorResponse
+    * @return
+    */
+   private Page getDisplay(ProcessorResponse processorResponse)
+   {
+      Page display = null;
+      
+      //Implement this with the new model
+      /*
+      org.jboss.portal.presentation.model.Page portalPage = processorResponse
+      .findDisplayedPage();
+
+      // Construct the ajax currentPage object from the portalPage that has been
+      // chosen to be displayed
+      if (portalPage != null)
+      {
+         display = new Page();
+         display.setName(portalPage.getName());
+         List pageWindows = portalPage.getWindows();
+         if(pageWindows != null && pageWindows.size()>0)
+         {
+            Window[] windows = new Window[pageWindows.size()];
+            display.setWindows(windows);
+            for(int i=0; i<pageWindows.size(); i++)
+            {
+               org.jboss.portal.presentation.model.Window pageWindow = (org.jboss.portal.presentation.model.Window)pageWindows.get(i);
+               Window window = new Window();
+               window.setName(pageWindow.getName());
+               window.setContent(pageWindow.getContent());
+               windows[i] = window;               
+            }
+         }
+      }
+      */
+      
+      return display;
+   }
+   
+   /**
+    * 
+    *
+    */
+   private void callPortalServer() throws Exception
+   {
+      HttpServletRequest req = this.getThreadLocalRequest();
+      HttpServletResponse resp = this.getThreadLocalResponse();
+      String requestURI = req.getRequestURI();
+      String contextPath = req.getContextPath();
+      String portalHost = req.getServerName();
+      String portalRequestPath = requestURI.substring(contextPath.length());
+      String portalContextPath = requestURI.substring(0, contextPath.length());
+      Map queryParameterMap = new HashMap();
+      URLContext urlContext = URLContext.newInstance(req.isSecure(), req.getRemoteUser() != null);
+
+      Server server = this.entryPoint.getPortalServer();
+
+      //
+      ServerInvocationContext invocationCtx = new ServerInvocationContextImpl(
+         req,
+         resp,
+         portalHost,
+         portalRequestPath,
+         portalContextPath,
+         queryParameterMap,
+         null, //body parameter map is not applicable for asynchronous RPC calls
+         urlContext,
+         null //media type information is not applicable for asynchronous RPC calls
+         );
+      
+      //
+      ServerRequest request = new ServerRequest(invocationCtx);
+      request.setServer(server);
+
+      //
+      ServerResponse response = new ServerResponse(request, invocationCtx);
+
+      //
+      ServerInvocation invocation = new ServerInvocation(invocationCtx);
+      invocation.setRequest(request);
+      invocation.setResponse(response);
+
+      //
+      RequestControllerFactory controllerFactory = this.entryPoint.getControllerFactory();
+      RequestController controller = controllerFactory.createRequestController(invocation);
+      invocation.setHandler(new RequestControllerDispatcher(controller));
+      
+      InterceptorStackFactory stack = this.entryPoint.getInterceptorStackFactory();      
+      invocation.invoke(stack.getInterceptorStack());
+   }
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/classic/entry/PortalEntryPoint.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/classic/entry/PortalEntryPoint.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/classic/entry/PortalEntryPoint.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,609 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.impl.classic.entry;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.UnavailableException;
+
+import org.apache.log4j.Logger;
+import org.jboss.mx.util.MBeanProxy;
+import org.jboss.mx.util.MBeanServerLocator;
+import org.jboss.portal.common.http.QueryStringParser;
+import org.jboss.portal.common.invocation.InterceptorStackFactory;
+import org.jboss.portal.common.invocation.InvocationException;
+import org.jboss.portal.common.net.URLTools;
+import org.jboss.portal.common.util.Exceptions;
+import org.jboss.portal.server.PortalConstants;
+import org.jboss.portal.server.RequestController;
+import org.jboss.portal.server.RequestControllerDispatcher;
+import org.jboss.portal.server.RequestControllerFactory;
+import org.jboss.portal.server.Server;
+import org.jboss.portal.server.ServerException;
+import org.jboss.portal.server.ServerInvocation;
+import org.jboss.portal.server.ServerInvocationContext;
+import org.jboss.portal.server.ServerRequest;
+import org.jboss.portal.server.ServerResponse;
+import org.jboss.portal.server.impl.ServerInvocationContextImpl;
+import org.jboss.portal.server.request.URLContext;
+import org.jboss.portal.presentation.layout.LayoutManager;
+import org.jboss.portal.presentation.impl.classic.layout.FlexibleGrid;
+import org.jboss.portal.presentation.impl.classic.layout.FlexibleGridConstraints;
+import org.jboss.portal.presentation.impl.classic.layout.FlexibleGridLayoutManager;
+import org.jboss.portal.presentation.impl.classic.layout.RegionConstraints;
+import org.jboss.portal.presentation.impl.classic.layout.RegionLayoutManager;
+import org.jboss.portal.presentation.server.ProcessorResponse;
+import org.jboss.portal.presentation.entry.EntryPoint;
+
+/**
+ * The Portal Server Entry Point for classic html mode
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public class PortalEntryPoint extends HttpServlet
+{
+   /**
+    * 
+    */
+   private Logger log = Logger.getLogger(getClass());
+   
+   /** . */
+   private static final int GET_METHOD = 0;
+
+   /** . */
+   private static final int POST_METHOD = 1;
+
+   /** Describes a default servlet mapping. */
+   private static final int DEFAULT_SERVLET_MAPPING = 0;
+
+   /** Describes a root path mapping. */
+   private static final int ROOT_PATH_MAPPING = 1;
+
+   /** Describes a path mapping. */
+   private static final int PATH_MAPPING = 2;
+   
+   /** Are we or not the default servlet ? */
+   private boolean asDefaultServlet = false;
+   
+   /**
+    * 
+    */
+   private EntryPoint entryPoint = null;
+   
+   /** Configure the as default servlet. */
+   public void init() throws ServletException
+   {
+      asDefaultServlet = getAsDefaultServletInitValue();
+      try
+      {
+         MBeanServer mbeanServer = MBeanServerLocator.locateJBoss();
+         this.entryPoint = (EntryPoint) MBeanProxy.get(EntryPoint.class, new ObjectName(
+               this.getInitParameter("entryPointServiceName")),
+               mbeanServer);
+      }
+      catch (Exception e)
+      {
+         this.entryPoint = null;
+         String msg = "Portal Entry Point could not be created";
+         log.error(msg, e);
+         throw new UnavailableException(msg);
+      }
+   }
+   
+   /**
+    * 
+    */
+   protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+   {
+      //
+      String servletPath = req.getServletPath();
+      String requestURI = req.getRequestURI();
+      String contextPath = req.getContextPath();
+      
+      String resource = req.getRequestURI().replaceFirst(contextPath, "");
+      while(resource.startsWith("/"))
+      {
+         if(resource.length() > 1)
+         {
+            resource = resource.substring(1);
+         }
+         else
+         {
+            resource = "";
+         }
+      }
+      
+      if(resource == null || resource.trim().length() == 0)
+      {
+         resp.sendRedirect("index.html");
+         return;
+      }
+      
+      int method;
+      if ("GET".equals(req.getMethod()))
+      {
+         method = GET_METHOD;
+      }
+      else if ("POST".equals(req.getMethod()))
+      {
+         method = POST_METHOD;
+      }
+      else
+      {
+         throw new ServletException();
+      }
+
+      // Compute the media type in the content type
+      String mediaType = this.entryPoint.retrieveMediaType(req.getContentType());
+
+      // Only affect the charset encoding if the servlet container will decode the request
+      if (method == POST_METHOD && PortalConstants.APPLICATION_X_WWW_FORM_URLENCODED.equals(mediaType))
+      {
+         // Now we must ensure that we have either an equals or a trailing space after the media-type
+         String characterEncoding = req.getCharacterEncoding();
+         if (characterEncoding == null)
+         {
+            // Set out charset for the portal request
+            req.setCharacterEncoding(PortalConstants.UTF_8.name());
+         }
+         else
+         {
+            Charset charset = Charset.forName(characterEncoding);
+            if (!PortalConstants.UTF_8.equals(charset))
+            {
+               throw new ServletException("Unaccepted charset " + characterEncoding);
+            }
+         }
+      }
+
+      // Determine the mapping we have
+      int mapping = DEFAULT_SERVLET_MAPPING;
+      if (!asDefaultServlet)
+      {
+         if (servletPath.length() == 0)
+         {
+            mapping = ROOT_PATH_MAPPING;
+         }
+         else
+         {
+            mapping = PATH_MAPPING;
+         }
+      }
+
+      // Determine the host for this request
+      String portalHost = req.getServerName();
+
+      // Determine the request path
+      String portalRequestPath = null;
+      String portalContextPath = null;
+      switch (mapping)
+      {
+         case DEFAULT_SERVLET_MAPPING:
+            portalRequestPath = requestURI.substring(contextPath.length());
+            portalContextPath = requestURI.substring(0, contextPath.length());
+            break;
+         case ROOT_PATH_MAPPING:
+            portalRequestPath = requestURI.substring(contextPath.length());
+            portalContextPath = requestURI.substring(0, contextPath.length());
+            break;
+         case PATH_MAPPING:
+            portalRequestPath = requestURI.substring(contextPath.length() + servletPath.length());
+            portalContextPath = requestURI.substring(0, contextPath.length() + servletPath.length());
+            break;
+      }
+
+      // Apply the url decoding
+      portalRequestPath = URLTools.decodeXWWWFormURL(portalRequestPath);
+      portalContextPath = URLTools.decodeXWWWFormURL(portalContextPath);
+
+      //
+      URLContext urlContext = URLContext.newInstance(req.isSecure(), req.getRemoteUser() != null);
+
+      // ***************
+      // ***************
+      // ***************
+      // ***************
+
+      // Parse the query string to have the get parameters
+      // The resulting map has its parameters decoded from the x-www-form-url encoding
+      Map queryParameterMap = Collections.EMPTY_MAP;
+      String queryString = req.getQueryString();
+      if (queryString != null)
+      {
+         queryParameterMap = QueryStringParser.parseQueryString(queryString);
+      }
+
+      //
+      Map bodyParameterMap = null;
+      if (method == POST_METHOD && PortalConstants.APPLICATION_X_WWW_FORM_URLENCODED.equals(mediaType))
+      {
+         bodyParameterMap = Collections.EMPTY_MAP;
+         for (Iterator i = req.getParameterMap().entrySet().iterator(); i.hasNext();)
+         {
+            Map.Entry entry = (Map.Entry)i.next();
+
+            // Get param name
+            String paramName = (String)entry.getKey();
+
+            // Values that are aggregated from the query string and the body
+            String[] paramValues = (String[])entry.getValue();
+
+            // Values decoded from the query string
+            String[] queryValues = (String[])queryParameterMap.get(paramName);
+            if (queryValues != null)
+            {
+               int bodyValuesLength = paramValues.length - queryValues.length;
+               if (bodyValuesLength > 0)
+               {
+                  String[] bodyValues = new String[bodyValuesLength];
+                  System.arraycopy(paramValues, queryValues.length, bodyValues, 0, bodyValuesLength);
+                  if (bodyParameterMap.isEmpty())
+                  {
+                     bodyParameterMap = new HashMap();
+                  }
+                  bodyParameterMap.put(paramName, bodyValues);
+               }
+            }
+            else
+            {
+               if (bodyParameterMap.isEmpty())
+               {
+                  bodyParameterMap = new HashMap();
+               }
+               bodyParameterMap.put(paramName, paramValues);
+            }
+         }
+
+         // Make the map unmodifiable
+         bodyParameterMap = bodyParameterMap.isEmpty() ? bodyParameterMap : Collections.unmodifiableMap(bodyParameterMap);
+      }
+
+      // ***************
+      // ***************
+      // ***************
+      // ***************
+
+      //
+      Server server = this.entryPoint.getPortalServer();
+
+      //
+      ServerInvocationContext invocationCtx = new ServerInvocationContextImpl(
+         req,
+         resp,
+         portalHost,
+         portalRequestPath,
+         portalContextPath,
+         queryParameterMap,
+         bodyParameterMap,
+         urlContext,
+         mediaType);
+
+      //
+      ServerRequest request = new ServerRequest(invocationCtx);
+      request.setServer(server);
+
+      //
+      ServerResponse response = new ServerResponse(request, invocationCtx);
+
+      //
+      ServerInvocation invocation = new ServerInvocation(invocationCtx);
+      invocation.setRequest(request);
+      invocation.setResponse(response);
+
+      //
+      RequestControllerFactory controllerFactory = this.entryPoint.getControllerFactory();
+      RequestController controller = controllerFactory.createRequestController(invocation);
+      invocation.setHandler(new RequestControllerDispatcher(controller));
+
+      //
+      try
+      {
+         InterceptorStackFactory stack = this.entryPoint.getInterceptorStackFactory();
+         invocation.invoke(stack.getInterceptorStack());         
+      }
+      catch (ServerException e)
+      {
+         log.error("Server exception", e);
+         Throwable nested = Exceptions.unwrap(e);
+         throw new ServletException(nested);
+      }
+      catch (InvocationException e)
+      {
+         log.error("Invocation exception", e);
+         Throwable nested = Exceptions.unwrap(e);
+         throw new ServletException(nested);
+      }
+      catch (ServletException e)
+      {
+         throw e;
+      }
+      catch (IOException e)
+      {
+         throw e;
+      }
+      catch (Exception e)
+      {
+         log.error("Unexpected exception", e);
+         Throwable nested = Exceptions.unwrap(e);
+         throw new ServletException(nested);
+      }
+   } 
+   
+   /**
+    * Return the value for the servlet mapping. This implementation get the
+    * value from an init parameter of the servlet called <b>asDefaultServlet</b>
+    */
+   private boolean getAsDefaultServletInitValue()
+   {
+      ServletConfig config = getServletConfig();
+      String value = config.getInitParameter("asDefaultServlet");
+      if ("true".equalsIgnoreCase(value))
+      {
+         log.debug("Servlet loaded as default servlet mapping");
+         return true;
+      }
+      else if ("false".equalsIgnoreCase(value))
+      {
+         log.debug("Servlet loaded as path mapping servlet");
+         return false;
+      }
+      else
+      {
+         log.warn("Servlet mapping cannot be determined with init parameter value="
+                     + value);
+         return false;
+      }
+   }   
+   // ---------All these are just helper methods for the prototype-----------------------------------------------------------------------------------------------
+   //----It containts mostly hard coded logic for the prototype-------------------------------------------------------------------------------------------------
+   /**
+    * Based on the latest design discussion, this method is not needed.
+    * 
+    * This will be an implementation detail of the UIServer processing the Response that is sent back to it
+    * from the Core Portal Processor
+    * 
+    * @param clientConnection
+    * @param page
+    */
+   /*private void render(PrintWriter clientConnection, Page pageResult)
+   {            
+      //Some flexible grid layout testing code
+      Object[] gridData = this.getFlexibleGridLayoutManager(pageResult);
+      Page page = (Page)gridData[0];
+      LayoutManager layoutManager = (LayoutManager)gridData[1]; 
+      
+      //Some region layout testing code
+      //Object[] regionData = this.getRegionBasedLayoutManager(pageResult);
+      //Page page = (Page)regionData[0];
+      //LayoutManager layoutManager = (LayoutManager)regionData[1];
+            
+      //Peform Page Layout
+      String output = layoutManager.doLayout(page);
+      
+      
+      //Create the final output...Also hardcoded without any preprocessing/postprocessing etc
+      StringBuffer buffer = new StringBuffer();      
+      buffer.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>JBoss Portal UIServer</title><link rel=\"stylesheet\" id=\"dyna_css\" href=\"/portal-ajax/dyna/style.css\" type=\"text/css\"/><link rel=\"stylesheet\" type=\"text/css\" id=\"main_css\" href=\"/portal-core/themes/renaissance/portal_style.css\"/><link rel=\"shortcut icon\" href=\"/portal-core/themes/renaissance/images/favicon.ico\" /><link rel=\"icon\" type=\"image/gif\" href=\"/portal-core/themes/renaissance/images/animated_favicon1.gif\" /></head><body id=\"body\">\n");
+      buffer.append(output);
+      buffer.append("</body></html>\n");
+      
+      
+      //Sending the results back to the Client
+      clientConnection.write(buffer.toString());
+      clientConnection.flush();
+   }*/
+   
+   /**
+    * 
+    */
+   /*private Object[] getFlexibleGridLayoutManager(Page pageResult)
+   {
+      
+      Page page = new Page();
+      Container header = new Container("header");
+      Container leftPanel = new Container("leftPanel");
+      Container mainPanel = new Container("mainPanel");
+      Window headerTabsWindow = new Window("header-tabs-window");
+      Window menuWindow = new Window("menu-window");
+      Window leftPanelWindow1 = new Window("left-panel-window1");
+      Window leftPanelWindow2 = new Window("left-panel-window2");
+      Window mainPanelWindow = new Window("main-panel-window");
+      header.addComponent(headerTabsWindow);
+      header.addComponent(menuWindow);
+      leftPanel.addComponent(leftPanelWindow1);
+      leftPanel.addComponent(leftPanelWindow2);
+      mainPanel.addComponent(mainPanelWindow);
+            
+      //Setup the Grid for headerTabs container
+      page.addContainer(header);
+      FlexibleGrid headerGrid = this.getGrid("header", 1, 2);
+      FlexibleGridConstraints[] headerTabConstraints  = { this.getConstraints("header-tabs-window", "100", 0, 0, 10, 0, 0, 0),
+      this.getConstraints("menu-window", "100", 0, 0, 0, 0, 0, 1) };
+      headerGrid.setConstraints(headerTabConstraints);      
+      
+      //Setup the Grid for left panel container
+      page.addContainer(leftPanel);
+      FlexibleGrid leftPanelGrid = this.getGrid("leftPanel", 2, 1);
+      FlexibleGridConstraints[] leftPanelConstraints  = { this.getConstraints("left-panel-window1", "75", 0, 0, 0, 0, 0, 0), 
+      this.getConstraints("left-panel-window2", "75", 0, 0, 0, 0, 1, 0) };      
+      leftPanelGrid.setConstraints(leftPanelConstraints);
+      
+      //Setup the Grid for main panel container
+      page.addContainer(mainPanel);
+      FlexibleGrid mainPanelGrid = this.getGrid("mainPanel", 1, 1);
+      FlexibleGridConstraints[] mainPanelConstraints  = { this.getConstraints("main-panel-window", "100", 0, 0, 0, 0, 0, 0) };
+      mainPanelGrid.setConstraints(mainPanelConstraints);
+      
+      //Setup the FlexibleGrid Layout Manager with the different grids
+      FlexibleGrid[] row1 = { headerGrid };
+      FlexibleGrid[] row2 = { leftPanelGrid, mainPanelGrid };
+      FlexibleGridLayoutManager layoutManager = new FlexibleGridLayoutManager();
+      layoutManager.addRowOfGrids(row1);
+      layoutManager.addRowOfGrids(row2);
+            
+      //Populate the grid windows with proper content      
+      List windows = pageResult.getWindows();
+      int counter = 0;
+      for(Iterator itr=windows.iterator();itr.hasNext();)
+      {
+         Window result = (Window)itr.next();
+         
+         switch(counter)
+         {
+            case 0:
+               leftPanelWindow1.setContent(result.getContent());
+            break;
+            
+            case 1:
+               leftPanelWindow2.setContent(result.getContent());
+            break;
+               
+            case 2:
+               mainPanelWindow.setContent(result.getContent());
+            break;
+               
+            case 3:
+               menuWindow.setContent(result.getContent());
+            break;
+               
+            case 4:
+               headerTabsWindow.setContent(result.getContent());
+            break;
+         }
+         
+         counter++;         
+      }
+      
+      return new Object[]{page, layoutManager};
+   }*/
+      
+   
+   /**
+    * 
+    * @param containerId
+    * @param rows
+    * @param columns
+    * @return
+    */
+   /*private FlexibleGrid getGrid(String containerId,int rows, int columns)
+   {
+      FlexibleGrid grid = new FlexibleGrid(containerId);
+      grid.setRows(rows);
+      grid.setColumns(columns);
+      return grid;
+   }*/
+   
+   /**
+    * 
+    * @param componentId
+    * @param widthPercentage
+    * @param top
+    * @param bottom
+    * @param left
+    * @param right
+    */
+   /*private FlexibleGridConstraints getConstraints(String componentId, String widthPercentage, int top, int bottom, int left, int right, int row, int column)
+   {
+      FlexibleGridConstraints constraints = new FlexibleGridConstraints();
+      constraints.setComponentId(componentId);
+      constraints.setWidthPercentage(widthPercentage);
+      constraints.setRow(row);
+      constraints.setColumn(column);
+      constraints.setTop(top);
+      constraints.setBottom(bottom);
+      constraints.setLeft(left);
+      constraints.setRight(right);
+      return constraints;
+   }*/
+   
+   /**
+    * 
+    * @param pageResult
+    * @return
+    */
+   /*private Object[] getRegionBasedLayoutManager(Page pageResult)
+   {
+      Page page = new Page();
+      Container left = new Container("left");
+      Container center = new Container("center");
+      page.addContainer(left);
+      page.addContainer(center);
+            
+      //Populate the grid windows with proper content      
+      List windows = pageResult.getWindows();
+      int counter = 0;
+      for(Iterator itr=windows.iterator();itr.hasNext();)
+      {
+         Window result = (Window)itr.next();
+         Window uiWindow = new Window(result.getId());
+         uiWindow.setContent(result.getContent());
+         switch(counter)
+         {
+            case 0:
+               left.addComponent(uiWindow);
+            break;
+            
+            case 1:
+               left.addComponent(uiWindow);
+            break;
+               
+            case 2:
+               center.addComponent(uiWindow);
+            break;
+               
+            case 3:
+               center.addComponent(uiWindow);
+            break;
+               
+            case 4:
+               left.addComponent(uiWindow);
+            break;
+         }
+         
+         counter++;         
+      }
+      
+      RegionLayoutManager layoutManager = new RegionLayoutManager();
+      RegionConstraints leftConstraints = new RegionConstraints("left", RegionConstraints.LEFT);
+      RegionConstraints centerConstraints = new RegionConstraints("center", RegionConstraints.CENTER);
+      layoutManager.addRegionConstraints(leftConstraints);
+      layoutManager.addRegionConstraints(centerConstraints);
+      
+      return new Object[]{page, layoutManager};
+   }*/
+}

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/entry/EntryPointImpl.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/entry/EntryPointImpl.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/impl/entry/EntryPointImpl.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,138 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat                                               *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
+ * contributors as indicated by the @authors tag. See the                     *
+ * copyright.txt in the distribution for a full listing of                    *
+ * individual contributors.                                                   *
+ *                                                                            *
+ * This is free software; you can redistribute it and/or modify it            *
+ * under the terms of the GNU Lesser General Public License as                *
+ * published by the Free Software Foundation; either version 2.1 of           *
+ * the License, or (at your option) any later version.                        *
+ *                                                                            *
+ * This software is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
+ * Lesser General Public License for more details.                            *
+ *                                                                            *
+ * You should have received a copy of the GNU Lesser General Public           *
+ * License along with this software; if not, write to the Free                *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
+ ******************************************************************************/
+package org.jboss.portal.presentation.impl.entry;
+
+import org.jboss.portal.common.invocation.InterceptorStackFactory;
+import org.jboss.portal.server.RequestControllerFactory;
+import org.jboss.portal.server.Server;
+import org.jboss.portal.jems.as.system.AbstractJBossService;
+import org.jboss.portal.presentation.entry.EntryPoint;
+
+/**
+ * Implementation of an Entry Point Utility
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ *
+ */
+public class EntryPointImpl extends AbstractJBossService implements EntryPoint
+{
+   /** The interceptor stack. */
+   private InterceptorStackFactory interceptorStackFactory = null;
+
+   /** The controller for this servlet. */
+   private RequestControllerFactory controllerFactory = null;
+   
+   /**
+    * 
+    */
+   private Server portalServer = null;
+
+         
+   /**
+    * 
+    * @return
+    */
+   public RequestControllerFactory getControllerFactory()
+   {
+      return controllerFactory;
+   }
+
+
+   /**
+    * 
+    * @param controllerFactory
+    */
+   public void setControllerFactory(RequestControllerFactory controllerFactory)
+   {
+      this.controllerFactory = controllerFactory;
+   }
+
+   
+   /**
+    * 
+    * @return
+    */
+   public InterceptorStackFactory getInterceptorStackFactory()
+   {
+      return interceptorStackFactory;
+   }
+
+
+   /**
+    * 
+    * @param interceptorStackFactory
+    */
+   public void setInterceptorStackFactory(
+         InterceptorStackFactory interceptorStackFactory)
+   {
+      this.interceptorStackFactory = interceptorStackFactory;
+   }
+   
+   /**
+    * 
+    * @return
+    */
+   public Server getPortalServer()
+   {
+      return portalServer;
+   }
+
+
+   /**
+    * 
+    * @param portalServer
+    */
+   public void setPortalServer(Server portalServer)
+   {
+      this.portalServer = portalServer;
+   }
+
+
+   /**
+    * 
+    * @param contentType
+    * @return
+    */
+   public String retrieveMediaType(String contentType)
+   {
+      String mediaType = contentType;
+
+      //
+      if (mediaType != null)
+      {
+         // Remove any parameters
+         int index = mediaType.indexOf(';');
+         if (index != -1)
+         {
+            mediaType = contentType.substring(0, index);
+         }
+
+         // Trim
+         mediaType = mediaType.trim();
+
+         // Media type matching is case insensitive, so we convert to lower case
+         mediaType = mediaType.toLowerCase();
+      }
+      return mediaType;
+   }
+}

Deleted: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/model/Portal.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/model/Portal.java	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/model/Portal.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -1,39 +0,0 @@
-/******************************************************************************
- * JBoss, a division of Red Hat                                               *
- * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
- * contributors as indicated by the @authors tag. See the                     *
- * copyright.txt in the distribution for a full listing of                    *
- * individual contributors.                                                   *
- *                                                                            *
- * This is free software; you can redistribute it and/or modify it            *
- * under the terms of the GNU Lesser General Public License as                *
- * published by the Free Software Foundation; either version 2.1 of           *
- * the License, or (at your option) any later version.                        *
- *                                                                            *
- * This software is distributed in the hope that it will be useful,           *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
- * Lesser General Public License for more details.                            *
- *                                                                            *
- * You should have received a copy of the GNU Lesser General Public           *
- * License along with this software; if not, write to the Free                *
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
- ******************************************************************************/
-package org.jboss.portal.presentation.model;
-
-
-/**
- * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
- *
- */
-public class Portal extends PortalObject
-{
-   /**
-    * 
-    */
-   public String toString()
-   {
-      return "Portal: "+super.toString();
-   }
-}

Deleted: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/model/PortalObject.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/model/PortalObject.java	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/model/PortalObject.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -1,110 +0,0 @@
-/******************************************************************************
- * JBoss, a division of Red Hat                                               *
- * Copyright 2006, Red Hat Middleware, LLC, and individual                    *
- * contributors as indicated by the @authors tag. See the                     *
- * copyright.txt in the distribution for a full listing of                    *
- * individual contributors.                                                   *
- *                                                                            *
- * This is free software; you can redistribute it and/or modify it            *
- * under the terms of the GNU Lesser General Public License as                *
- * published by the Free Software Foundation; either version 2.1 of           *
- * the License, or (at your option) any later version.                        *
- *                                                                            *
- * This software is distributed in the hope that it will be useful,           *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
- * Lesser General Public License for more details.                            *
- *                                                                            *
- * You should have received a copy of the GNU Lesser General Public           *
- * License along with this software; if not, write to the Free                *
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
- ******************************************************************************/
-package org.jboss.portal.presentation.model;
-
-import java.io.Serializable;
-
-/**
- * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
- *
- */
-public abstract class PortalObject implements Serializable
-{
-   protected String id = null;
-   protected String name = null;
-         
-   /**
-    * 
-    *
-    */
-   public PortalObject()
-   {
-   }
-   
-   /**
-    * 
-    * @param id
-    * @param name
-    * @param parent
-    * @param children
-    */
-   public PortalObject(String id, String name)
-   {
-      this.id = id;
-      this.name = name;
-   }
-
-   /**
-    * 
-    * @return
-    */
-   public String getId()
-   {
-      return id;
-   }
-
-   /**
-    * 
-    * @param id
-    */
-   public void setId(String id)
-   {
-      this.id = id;
-   }
-
-   /**
-    * 
-    * @return
-    */
-   public String getName()
-   {
-      return name;
-   }
-
-   /**
-    * 
-    * @param name
-    */
-   public void setName(String name)
-   {
-      this.name = name;
-   }
-   
-   /**
-    * 
-    */
-   public String toString()
-   {
-      String rep = null;
-      
-      StringBuffer buffer = new StringBuffer();
-      buffer.append("[");
-      buffer.append("id="+this.id+",");
-      buffer.append("name="+this.name);
-      buffer.append("]");
-      
-      rep = buffer.toString();
-      
-      return rep;
-   }
-}

Modified: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/server/ProcessorResponse.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/server/ProcessorResponse.java	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/server/ProcessorResponse.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -23,9 +23,9 @@
 package org.jboss.portal.presentation.server;
 
 import java.io.Serializable;
-import java.util.List;
 
 import org.jboss.portal.web.ServletContextDispatcher;
+import org.jboss.portal.presentation.action.server.ServerResponse;
 
 /**
  * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
@@ -36,39 +36,22 @@
    /**
     * 
     */
-   private ServletContextDispatcher dispatcher = null;
+   private ServletContextDispatcher dispatcher = null; 
    
    /**
-    * Contains a list of pages that need to be updated on the client. These pages may not necessarily
-    * be the currently displayed page, but nevertheless, these are pages whose window content changed
-    * as a result of this particular Portal request processing.
-    * 
-    * For most usecases this probably only consist of the Page that is currently being displayed on the client
+    * The ServerResponse generated by processing the ProcessorRequest by the Processor
     */
-   private List updatedPages = null;
-   
+   private ServerResponse response = null;
+         
    /**
-    * Content Type of the response being sent back to the client
-    */
-   private String contentType = null;
-   
-   /**
-    * Character Set of the response being sent back to the client
-    */
-   private String charSet = null;
-      
-   
-   /**
     * 
     * @param dispatcher
     * @param updatedPages
     */
-   public ProcessorResponse(ServletContextDispatcher dispatcher, String contentType, String charSet, List updatedPages)
+   public ProcessorResponse(ServletContextDispatcher dispatcher, ServerResponse response)
    {
-      this.dispatcher = dispatcher;
-      this.contentType = contentType;
-      this.charSet = charSet;
-      this.updatedPages = updatedPages;      
+      this.dispatcher = dispatcher;            
+      this.response = response;
    }
    
    /**
@@ -93,77 +76,17 @@
     * 
     * @return
     */
-   public List getUpdatedPages()
+   public ServerResponse getResponse()
    {
-      return updatedPages;
+      return response;
    }
 
    /**
     * 
-    * @param updatedPages
+    * @param response
     */
-   public void setUpdatedPages(List updatedPages)
+   public void setResponse(ServerResponse response)
    {
-      this.updatedPages = updatedPages;
-   }
-
-   /**
-    * 
-    * @return
-    */
-   public String getCharSet()
-   {
-      return charSet;
-   }
-
-   /**
-    * 
-    * @param charSet
-    */
-   public void setCharSet(String charSet)
-   {
-      this.charSet = charSet;
-   }
-
-   /**
-    * 
-    * @return
-    */
-   public String getContentType()
-   {
-      return contentType;
-   }
-
-   /**
-    * 
-    * @param contentType
-    */
-   public void setContentType(String contentType)
-   {
-      this.contentType = contentType;
-   }
-   
-   /**
-    * 
-    * @return
-    */
-   /*public Page findDisplayedPage()
-   {
-      Page displayedPage = null;
-      
-      if(this.updatedPages != null)
-      {
-         for(int i=0; i<this.updatedPages.size(); i++)
-         {
-            Page cour = (Page)this.updatedPages.get(i);
-            if(cour.isCurrentlyDisplayed())
-            {
-               displayedPage = cour;
-               break;
-            }
-         }
-      }
-      
-      return displayedPage;
-   }*/
+      this.response = response;
+   }   
 }

Added: branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/test/ajax/PortletServiceImpl.java
===================================================================
--- branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/test/ajax/PortletServiceImpl.java	                        (rev 0)
+++ branches/UIServer/uiserver/src/main/org/jboss/portal/presentation/test/ajax/PortletServiceImpl.java	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,232 @@
+package org.jboss.portal.presentation.test.ajax;
+
+import java.io.InputStream;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.jboss.portal.presentation.ajax.client.PortletService;
+import org.jboss.portal.presentation.ajax.client.protocol.Page;
+import org.jboss.portal.presentation.ajax.client.protocol.Window;
+
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+/**
+ * This is just a STUB server side component to test the client side components
+ * of the GWT-based AJAX UI
+ * 
+ * Only used for Prototyping stuff
+ * 
+ * @author <a href="mailto:sshah at redhat.com">Sohil Shah</a>
+ * 
+ */
+public class PortletServiceImpl extends RemoteServiceServlet implements
+      PortletService
+{
+   /**
+    * 
+    */
+   public String getPortlet(String portletId)
+   {
+      String portletContent = null;
+
+      String contentPath = portletId;
+      InputStream is = null;
+      try
+      {
+         is = Thread.currentThread().getContextClassLoader()
+               .getResourceAsStream(contentPath);
+         StringBuffer contentBuffer = new StringBuffer();
+         int bytesRead = 0;
+         byte[] data = new byte[1024];
+         while ((bytesRead = is.read(data)) != -1)
+         {
+            byte[] cour = new byte[bytesRead];
+            System.arraycopy(data, 0, cour, 0, bytesRead);
+            contentBuffer.append(new String(cour));
+         }
+         portletContent = contentBuffer.toString();
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException(e);
+      }
+      finally
+      {
+         if (is != null)
+         {
+            try
+            {
+               is.close();
+            }
+            catch (Exception e)
+            {
+            }
+         }
+      }
+
+      return portletContent;
+   }
+
+   /**
+    * 
+    * @param pageId
+    * @return
+    */
+   public Page getPage(String pageId)
+   {
+      Page page = new Page();
+      page.setName(pageId);
+
+      if (pageId.equals("index") || pageId.equals("Page 1"))
+      {
+         String weatherContent = this.getPortlet("weatherPortlet.html");
+         String cmsContent = this.getPortlet("cmsPortlet.html");
+         Window[] windows = new Window[2];
+         page.setWindows(windows);
+
+         Window weatherWindow = new Window();
+         weatherWindow.setName("weatherPortlet");
+         weatherWindow.setContent(weatherContent);
+
+         Window cmsWindow = new Window();
+         cmsWindow.setName("cmsPortlet");
+         cmsWindow.setContent(cmsContent);
+
+         windows[0] = weatherWindow;
+         windows[1] = cmsWindow;
+      }
+      else if (pageId.equals("Page 2"))
+      {
+         String weatherContent = this.getPortlet("weatherPortlet.html");
+         Window[] windows = new Window[1];
+         page.setWindows(windows);
+
+         Window weatherWindow = new Window();
+         weatherWindow.setName("weatherPortlet");
+         weatherWindow.setContent(weatherContent);
+
+         windows[0] = weatherWindow;
+      }
+      else if (pageId.equals("Page 3"))
+      {
+         String cmsContent = this.getPortlet("cmsPortlet.html");
+         Window[] windows = new Window[1];
+         page.setWindows(windows);
+
+         Window cmsWindow = new Window();
+         cmsWindow.setName("cmsPortlet");
+         cmsWindow.setContent(cmsContent);
+
+         windows[0] = cmsWindow;
+      }
+
+      HttpServletRequest request = this.getThreadLocalRequest();
+      request.getSession().setAttribute("currentPage", page);
+
+      return page;
+   }
+
+   /**
+    * 
+    * @param window
+    * @param state
+    */
+   public Page setState(String window, String newState)
+   {
+      HttpServletRequest request = this.getThreadLocalRequest();
+      Page page = (Page) request.getSession().getAttribute("currentPage");
+
+      Window selectedWindow = this.findWindow(page, window);
+      selectedWindow.setState(newState);
+      if (selectedWindow.getState().equals(Window.NORMAL))
+      {
+         if (selectedWindow.getName().equals("cmsPortlet"))
+         {
+            selectedWindow.setContent(this.getPortlet("cmsPortlet.html"));
+         }
+         else
+         {
+            selectedWindow.setContent(this.getPortlet("weatherPortlet.html"));
+         }
+         this.hideWindows(page.getWindows(), null, false);
+      }
+      else if (selectedWindow.getState().equals(Window.MINIMIZED))
+      {
+         selectedWindow.setContent("");
+         this.hideWindows(page.getWindows(), null, false);
+      }
+      if (selectedWindow.getState().equals(Window.MAXIMIZED))
+      {
+         if (selectedWindow.getName().equals("cmsPortlet"))
+         {
+            selectedWindow.setContent(this.getPortlet("cmsPortlet.html"));
+         }
+         else
+         {
+            selectedWindow.setContent(this.getPortlet("weatherPortlet.html"));
+         }
+         this.hideWindows(page.getWindows(), selectedWindow, true);
+      }
+
+      return page;
+   }
+
+   /**
+    * 
+    * @param window
+    * @param state
+    */
+   public Page setMode(String window, String newMode)
+   {
+      HttpServletRequest request = this.getThreadLocalRequest();
+      Page page = (Page) request.getSession().getAttribute("currentPage");
+
+      Window selectedWindow = this.findWindow(page, window);
+      selectedWindow.setMode(newMode);
+
+      return page;
+   }
+
+   /**
+    * 
+    * @param page
+    * @param windowName
+    * @return
+    */
+   private Window findWindow(Page page, String windowName)
+   {
+      Window window = null;
+
+      Window[] windows = page.getWindows();
+      for (int i = 0; i < windows.length; i++)
+      {
+         if (windows[i].getName().equals(windowName))
+         {
+            window = windows[i];
+            break;
+         }
+      }
+
+      return window;
+   }
+
+   /**
+    * 
+    * @param excludedWindow
+    * @param hide
+    */
+   private void hideWindows(Window[] windows, Window excludedWindow,
+         boolean hide)
+   {
+      for (int i = 0; i < windows.length; i++)
+      {
+         if (excludedWindow != null
+               && windows[i].getName().equals(excludedWindow.getName()))
+         {
+            continue;
+         }
+
+         windows[i].setVisible(!hide);
+      }
+   }
+}

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/AsyncPages.gwt.xml
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/AsyncPages.gwt.xml	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/AsyncPages.gwt.xml	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,12 @@
+<module>
+	<!-- Inherit the core Web Toolkit stuff -->
+	<inherits name="com.google.gwt.user.User"/>
+	<!-- Inherit the MyGWT toolkit -->
+	<inherits name='net.mygwt.ui.MyGWT'/>
+
+	<!-- Specify the app entry point class -->
+	<entry-point class="org.jboss.portal.presentation.ajax.client.AsyncPages"/>  
+	
+	<!-- RPC related configuration -->
+	<servlet path="/portletService" class="org.jboss.portal.presentation.impl.ajax.service.PortletServiceImpl"/>
+</module>

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/MyGWT.gwt.xml
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/MyGWT.gwt.xml	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/MyGWT.gwt.xml	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,9 @@
+<module>
+	<!-- Inherit the core Web Toolkit stuff -->
+	<inherits name="com.google.gwt.user.User"/>
+	<!-- Inherit the MyGWT toolkit -->
+	<inherits name='net.mygwt.ui.MyGWT'/>
+
+	<!-- Specify the app entry point class -->
+	<entry-point class="org.jboss.portal.presentation.ajax.client.MyGWTPrototype"/>
+</module>

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/PartialRefresh.gwt.xml
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/PartialRefresh.gwt.xml	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/PartialRefresh.gwt.xml	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,10 @@
+<module>
+	<!-- Inherit the core Web Toolkit stuff -->
+	<inherits name="com.google.gwt.user.User"/>
+
+	<!-- Specify the app entry point class -->
+	<entry-point class="org.jboss.portal.presentation.ajax.client.PartialRefresh"/>  
+	
+	<!-- RPC related configuration -->
+	<servlet path="/portletService" class="org.jboss.portal.presentation.impl.ajax.service.PortletServiceImpl"/>
+</module>

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/Portal.gwt.xml
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/Portal.gwt.xml	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/Portal.gwt.xml	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,12 @@
+<module>
+	<!-- Inherit the core Web Toolkit stuff -->
+	<inherits name="com.google.gwt.user.User"/>
+	<!-- Inherit the MyGWT toolkit -->
+	<inherits name='net.mygwt.ui.MyGWT'/>
+
+	<!-- Specify the app entry point class -->
+	<entry-point class="org.jboss.portal.presentation.ajax.client.Portal"/>  
+	
+	<!-- RPC related configuration. This is used only in Hosted Mode -->
+	<servlet path="/portalrpc" class="org.jboss.portal.presentation.test.ajax.HostedModeProxy"/>
+</module>

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/PortalLayout.gwt.xml
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/PortalLayout.gwt.xml	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/PortalLayout.gwt.xml	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,10 @@
+<module>
+	<!-- Inherit the core Web Toolkit stuff -->
+	<inherits name="com.google.gwt.user.User"/>
+
+	<!-- Specify the app entry point class -->
+	<entry-point class="org.jboss.portal.presentation.ajax.client.PortalLayout"/>  
+	
+	<!-- RPC related configuration -->
+	<servlet path="/portletService" class="org.jboss.portal.presentation.impl.ajax.service.PortletServiceImpl"/>
+</module>

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/asyncPages.html
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/asyncPages.html	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/asyncPages.html	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,27 @@
+<html>
+	<head>
+	
+		<!--                                           -->
+		<!-- Any title is fine                         -->
+		<!--                                           -->
+		<title>JBoss Portal</title>
+
+		<link href="portal.css" rel="stylesheet" type="text/css">
+
+		<!--                                           -->
+		<!-- This script loads your compiled module.   -->
+		<!-- If you add any GWT meta tags, they must   -->
+		<!-- be added before this line.                -->
+		<!--                                           -->
+		<script language='javascript' src='prototype.js'></script>		
+		<script language='javascript' src='org.jboss.portal.presentation.ajax.AsyncPages.nocache.js'></script>		
+	</head>
+
+	<!--                                           -->
+	<!-- The body can have arbitrary html, or      -->
+	<!-- you can leave the body empty if you want  -->
+	<!-- to create a completely dynamic ui         -->
+	<!--                                           -->
+	<body>		
+	</body>
+</html>

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/cmsPortlet.html
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/cmsPortlet.html	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/cmsPortlet.html	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,81 @@
+<style type="text/css">
+   #welcomelogo {
+      float: left;
+      margin: 30px 0px 30px 15px;
+   }
+
+   #welcometext {
+      margin: 30px 50px 30px 225px;
+   }
+
+   #welcomegreybox {
+      padding: 15px;
+      margin-bottom: 30px;
+   }
+
+   #welcomegreyboxTD {
+      border-left: 1px solid #d5d5d5;
+      padding-left: 15px;
+   }
+
+   #welcomegreybox h3 {
+      color: #5078aa;
+      font: bold 13px Helvetica, Arial, sans-serif;
+   }
+</style>
+
+<!--
+<div>
+  <img src="/portal/content/default/images/homeimg_main.png" width="560" height="160"/>
+</div>
+-->
+
+<!--
+<div id="welcomelogo"><img src="/portal/content/default/images/homeimg_jbosslogo.png" width="143" height="64"/></div>
+-->
+
+
+<p id="welcometext">JBoss Portal provides an open source platform for hosting and serving a portal Web interface,
+   publishing and managing its content, and customizing its experience. While most packaged Portal frameworks help
+   enterprises launch Portals more quickly, only JBoss Portal delivers the benefits of a zero-cost open source license
+   combined with a flexible and scalable underling platform.</p>
+
+<div id="welcomegreybox">
+   <table width="100%">
+      <tr>
+         <td valign="top"><h3>Support Services</h3>
+            <p>
+            	JBoss Inc. offers various support services tailored to fit your needs. <a href="portal/index.html">Explore</a>
+               support and service options for JBoss Portal.
+             </p>
+         </td>
+         <td valign="top" id="welcomegreyboxTD"><h3>PortletSwap</h3>
+            <p>
+            	<a href="http://www.portletswap.com">Portletswap.com</a> is an open community sponsored by JBoss, Inc. to facilitate the exchange of portlets and layouts for use in JBoss Portal.
+            </p>
+         </td>
+         <td valign="top" id="welcomegreyboxTD"><h3>Project Information</h3>
+            <p>Learn more about the <a href="/portal/index.html">JBoss Portal project</a>, on-going development, open
+               issues, and our
+               user and developer communities.
+         	</p>
+         </td>
+      </tr>
+   </table>
+
+</div>
+<p>Thank you for downloading and deploying JBoss Portal. We hope your enjoy working with it as much as we enjoy
+   developing it!</p>
+<p>Baci e abbracci,<br/>
+   The JBoss Portal Team.
+</p>
+
+<br/>
+
+<div>
+	<form name="testForm" method="post" action="portal/index.html">
+		<span>Param1:</span><input type="text" name="param1"/><br/>
+		<span>Param2:</span><input type="text" name="param2"/><br/>
+		<input type="submit"/>
+	</form>
+</div>
\ No newline at end of file

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/images/ico_16_maximize.gif
===================================================================
(Binary files differ)


Property changes on: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/images/ico_16_maximize.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/images/ico_16_minimize.gif
===================================================================
(Binary files differ)


Property changes on: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/images/ico_16_minimize.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/images/ico_16_normal.gif
===================================================================
(Binary files differ)


Property changes on: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/images/ico_16_normal.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/index.html
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/index.html	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/index.html	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,27 @@
+<html>
+	<head>
+	
+		<!--                                           -->
+		<!-- Any title is fine                         -->
+		<!--                                           -->
+		<title>JBoss Portal</title>
+
+		<link href="portal.css" rel="stylesheet" type="text/css">
+
+		<!--                                           -->
+		<!-- This script loads your compiled module.   -->
+		<!-- If you add any GWT meta tags, they must   -->
+		<!-- be added before this line.                -->
+		<!--                                           -->
+		<script language='javascript' src='prototype.js'></script>		
+		<script language='javascript' src='org.jboss.portal.presentation.ajax.Portal.nocache.js'></script>		
+	</head>
+
+	<!--                                           -->
+	<!-- The body can have arbitrary html, or      -->
+	<!-- you can leave the body empty if you want  -->
+	<!-- to create a completely dynamic ui         -->
+	<!--                                           -->
+	<body>												
+	</body>
+</html>

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/jspPortlet.html
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/jspPortlet.html	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/jspPortlet.html	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,42 @@
+<div class="portlet-container"><table width="100%" border="0" cellpadding="0" cellspacing="0"><tr><td class="portlet-titlebar-left"></td><td class="portlet-titlebar-center"><div class="portlet-titlebar-decoration"></div><span class="portlet-titlebar-title">Greetings!</span><div class="portlet-mode-container"><span title="minimized"><a class="portlet-mode-minimized" href="/portal/portal/default/default/JSPPortletWindow?windowstate=minimized">&nbsp;</a></span><span title="maximized"><a class="portlet-mode-maximized" href="/portal/portal/default/default/JSPPortletWindow?windowstate=maximized">&nbsp;</a></span></div></td><td class="portlet-titlebar-right"></td></tr><tr><td class="portlet-content-left"></td><td class="portlet-body"><div class="portlet-content-center">
+
+<table border="0" cellspacing="2" cellpadding="2">
+   <tr>
+      <td align="center"><a href="http://portal.demo.jboss.com" target="_blank"><img
+         src="/portal-jsp-samples/images/dodemo.gif" border="0"
+         alt="Try the latest release of JBoss Portal, live and online."></a>
+         <a href="http://labs.jboss.com/portal/jbossportal/download/index.html" target="_blank"><img
+            src="/portal-jsp-samples/images/getcode.gif" border="0"
+            alt="Download JBoss Portal and have it up and running in minutes."></a>
+         <a href="http://www.portletswap.com" target="_blank"><img
+            src="/portal-jsp-samples/images/accessorize.gif" border="0"
+            alt="Download portlets and layouts for your new JBoss Portal installation."></a></td>
+   </tr>
+   <tr>
+
+      <td></td>
+   </tr>
+   <tr>
+      <td class="portlet-section-alternate">
+         <font class="portlet-font">This is a basic installation of <b>JBoss Portal 2.8.0-SNAPSHOT</b>. You may
+            log in at any time, using the <i>Login</i> link at the top-right of this page, with the following
+            credentials:</font>
+      </td>
+
+   </tr>
+   <tr>
+      <td class="portlet-section-alternate" align="center">
+         <b>user/user</b> or <b>admin/admin</b>
+      </td>
+   </tr>
+   <tr>
+
+      <td align="center">
+         If you are in need of guidance with regards to navigating, configuring, or operating the portal, please view
+         our <a href="http://labs.jboss.com/portal/jbossportal/docs/index.html" target="_blank">online documentation</a>.
+      </td>
+   </tr>
+</table>
+</div></td><td class="portlet-content-right"></td></tr><tr><td class="portlet-footer-left"></td><td class="portlet-footer-center"></td><td class="portlet-footer-right"></td></tr></table>
+
+</div>
\ No newline at end of file

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/layout.html
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/layout.html	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/layout.html	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,59 @@
+<html>
+	<head>
+	
+		<!--                                           -->
+		<!-- Any title is fine                         -->
+		<!--                                           -->
+		<title>JBoss Portal</title>
+
+		<link href="portal.css" rel="stylesheet" type="text/css">
+
+		<!--                                           -->
+		<!-- This script loads your compiled module.   -->
+		<!-- If you add any GWT meta tags, they must   -->
+		<!-- be added before this line.                -->
+		<!--                                           -->
+		<script language='javascript' src='prototype.js'></script>		
+		<script language='javascript' src='org.jboss.portal.presentation.ajax.PortalLayout.nocache.js'></script>		
+	</head>
+
+	<!--                                           -->
+	<!-- The body can have arbitrary html, or      -->
+	<!-- you can leave the body empty if you want  -->
+	<!-- to create a completely dynamic ui         -->
+	<!--                                           -->
+	<body>
+		<!-- OPTIONAL: include this if you want history support -->
+		<iframe src="javascript:''" id="__gwt_historyFrame" style="width:0;height:0;border:0"></iframe>
+		
+		<h1>JBoss Portal</h1>
+		
+		<!-- Portal Portlet Layout capabilities Proof of Concept -->
+		<p>
+			Testing Vertical Column based Portlet Layout 
+		</p>				
+		<table align="center">
+			<tr>
+				<td id="leftPanel"></td>
+				<td id="centerPanel"></td>
+				<td id="rightPanel"></td>
+			</tr>			
+		</table>		
+		
+		<p>
+			Testing Flexible Grid based Portlet Layout 
+		</p>
+		<table align="center">
+			<tr>
+				<td id="cmsPortlet"></td>
+				<td id="jspPortlet"></td>
+				<td id="weatherPortlet"></td>
+			</tr>
+		</table>
+		<table align="center">
+			<tr>
+				<td id="flexGrid"></td>
+			</tr>
+		</table>						
+	</body>
+</html>

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/mygwt.html
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/mygwt.html	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/mygwt.html	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,30 @@
+<html>
+	<head>		
+		<title>JBoss Portal</title>
+
+        <!-- portal styles defined here -->
+		<link href="portal.css" rel="stylesheet" type="text/css">
+
+		<!--                                           -->
+		<!-- This script loads your compiled module.   -->
+		<!-- If you add any GWT meta tags, they must   -->
+		<!-- be added before this line.                -->
+		<!--                                           -->	
+		<script language='javascript' src='org.jboss.portal.presentation.ajax.MyGWT.nocache.js'></script>		
+	</head>
+
+	<!--                                           -->
+	<!-- The body can have arbitrary html, or      -->
+	<!-- you can leave the body empty if you want  -->
+	<!-- to create a completely dynamic ui         -->
+	<!--                                           -->
+	<body>		
+		<!-- MyGWT Proof of Concept -->			
+		<h1>MyGWT Prototype</h1><br/>				
+		<table align="center">						
+			<tr>
+				<td id="currentPage"></td>
+			</tr>			
+		</table>										
+	</body>
+</html>

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/partialRefresh.html
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/partialRefresh.html	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/partialRefresh.html	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,41 @@
+<html>
+	<head>
+	
+		<!--                                           -->
+		<!-- Any title is fine                         -->
+		<!--                                           -->
+		<title>JBoss Portal</title>
+
+		<link href="portal.css" rel="stylesheet" type="text/css">
+
+		<!--                                           -->
+		<!-- This script loads your compiled module.   -->
+		<!-- If you add any GWT meta tags, they must   -->
+		<!-- be added before this line.                -->
+		<!--                                           -->
+		<script language='javascript' src='prototype.js'></script>		
+		<script language='javascript' src='org.jboss.portal.presentation.ajax.PartialRefresh.nocache.js'></script>		
+	</head>
+
+	<!--                                           -->
+	<!-- The body can have arbitrary html, or      -->
+	<!-- you can leave the body empty if you want  -->
+	<!-- to create a completely dynamic ui         -->
+	<!--                                           -->
+	<body>
+		<!-- OPTIONAL: include this if you want history support -->
+		<iframe src="javascript:''" id="__gwt_historyFrame" style="width:0;height:0;border:0"></iframe>
+		
+		<h1>JBoss Portal</h1>
+		
+		<!--  Portal Partial Page Refresh Proof of Concept -->
+		<p>
+			Portal Partial Refresh Proof of Concept
+		</p>
+		<table align="center">
+			<tr>
+				<td id="page"></td>				
+			</tr>			
+		</table>		
+	</body>
+</html>

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/portal/index.html
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/portal/index.html	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/portal/index.html	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,76 @@
+<div class="portlet-container"><table width="100%" border="0" cellpadding="0" cellspacing="0"><tr><td class="portlet-titlebar-left"></td><td class="portlet-titlebar-center"><div class="portlet-titlebar-decoration"></div><span class="portlet-titlebar-title">Weather Portlet</span><div class="portlet-mode-container"><span title="minimized"><a class="portlet-mode-minimized" href="/portal/portal/default/default/2?windowstate=minimized">&nbsp;</a></span><span title="maximized"><a class="portlet-mode-maximized" href="/portal/portal/default/default/2?windowstate=maximized">&nbsp;</a></span></div></td><td class="portlet-titlebar-right"></td></tr><tr><td class="portlet-content-left"></td><td class="portlet-body"><div class="portlet-content-center"><br/>
+<div align="center">
+<font>
+<b>Miami, FL, US</b>
+</font>
+
+<br/>
+<br/>
+<table border="0" width="130">
+<tr>
+<td>
+<table height="130" border="0">
+<tr>
+<td align="center" class="portlet-section-header">Currently</td>
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">
+<img src="http://us.i1.yimg.com/us.yimg.com/i/us/we/52//28.gif"/>
+</td>
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">Mostly Cloudy</td>
+
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">86F</td>
+</tr>
+</table>
+</td>
+<td>
+<table height="130" border="0">
+<tr>
+<td valign="top" align="center" class="portlet-section-header">Thu</td>
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">
+<img src="http://us.i1.yimg.com/us.yimg.com/i/us/we/52//38.gif"/>
+</td>
+
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">Scattered Thunderstorms</td>
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">76F/86F</td>
+</tr>
+</table>
+</td>
+<td>
+<table height="130" border="0">
+<tr>
+<td valign="top" align="center" class="portlet-section-header">Fri</td>
+</tr>
+
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">
+<img src="http://us.i1.yimg.com/us.yimg.com/i/us/we/52//38.gif"/>
+</td>
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">Scattered Thunderstorms</td>
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">78F/89F</td>
+</tr>
+</table>
+</td>
+</tr>
+</table>
+
+<br/>
+<a target="_blank" href="http://us.rd.yahoo.com/dailynews/rss/weather/Miami__FL/*http://weather.yahoo.com/forecast/33145_f.html">Complete Forecast</a>
+</div>
+</div></td><td class="portlet-content-right"></td></tr><tr><td class="portlet-footer-left"></td><td class="portlet-footer-center"></td><td class="portlet-footer-right"></td></tr></table>
+
+</div>
\ No newline at end of file

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/portal.css
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/portal.css	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/portal.css	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,480 @@
+body {
+  background-color: white;
+  color: black;
+  font-family: Helvetica, Arial, sans-serif;
+  font-size: 10pt;
+  margin: 0px 20px 20px 20px;
+}
+
+h2 {
+  font-weight: normal;
+}
+
+table {
+  font-size: 100%;
+}
+
+code {
+  font-size: small;
+}
+
+a {
+  color: darkblue;
+}
+
+a:visited {
+  color: darkblue;
+}
+/*----------------Client-Side Ajax Agent styles-------------------------------------------------------------------------------------------------------------------------------*/
+.window-normal-button{ 
+	background: url(images/ico_16_normal.gif);
+}
+
+.window-minimize-button{		 
+	background: url(images/ico_16_minimize.gif);
+}
+
+.window-maximize-button{		
+	background: url(images/ico_16_maximize.gif);
+}
+/*-------------Core GWT styles------------------------------------------------------------------------------------------------------------------------------------*/
+.gwt-BorderedPanel {
+}
+
+.gwt-Button {
+  background:#f5f5f5;
+  border:1px solid #aaa;
+  border-top:1px solid #ddd;
+  border-left:1px solid #ddd;
+  padding: 2px;
+  width: 12em;
+}
+
+.gwt-Button:active {
+  border:1px solid #aaa;
+  border-bottom:1px solid #ccc;
+  border-right:1px solid #ccc;
+}
+
+.gwt-Button[disabled] {
+  background: #ccc;
+  border:1px solid #999;
+  border-top:1px solid #ccc;
+  border-left:1px solid #ccc;
+  color: #888;
+}
+
+.gwt-Canvas {
+}
+
+.gwt-CheckBox {
+}
+
+.gwt-DialogBox {
+  border: 2px outset;
+  background-color: white;
+}
+
+.gwt-DialogBox .Caption {
+  background-color: #C3D9FF;
+  padding: 3px;
+  margin: 2px;
+  font-weight: bold;
+  cursor: default;
+}
+
+.gwt-FileUpload {
+}
+
+.gwt-Frame {
+}
+
+.gwt-HTML {
+}
+
+.gwt-Hyperlink {
+}
+
+.gwt-Image {
+}
+
+.gwt-Label {
+}
+
+.gwt-ListBox {
+}
+
+.gwt-MenuBar {
+  background-color: #C3D9FF;
+  border: 1px solid #87B3FF;
+  cursor: default;
+}
+
+.gwt-MenuBar .gwt-MenuItem {
+  padding: 1px 4px 1px 4px;
+  cursor: default;
+}
+
+.gwt-MenuBar .gwt-MenuItem-selected {
+  background-color: #E8EEF7;
+}
+
+.gwt-PasswordTextBox {
+}
+
+.gwt-RadioButton {
+}
+
+.gwt-TabPanel {
+  margin-top: 4px;
+}
+
+.gwt-TabPanelBottom {
+  background-color: #E8EEF7;
+}
+
+.gwt-TabBar {
+  padding-top: 2px;
+  border-bottom: 4px solid #87B3FF;
+  background-color: #fff;
+}
+
+.gwt-TabBar .gwt-TabBarFirst {
+}
+
+.gwt-TabBar .gwt-TabBarRest {
+}
+
+.gwt-TabBar .gwt-TabBarItem {
+  padding: 4px;
+  cursor: pointer;
+  cursor: hand;
+
+  background-color: #e8eef7;
+  border-bottom: 2px solid white;
+  margin-right: 2px;
+}
+
+.gwt-TabBar .gwt-TabBarItem-selected {
+  padding: 4px;
+  font-weight: bold;
+  cursor: default;
+
+  background-color: #87b3ff;
+  border-bottom: 2px solid #87b3ff;
+  margin-right: 2px;
+}
+
+.gwt-TextArea {
+}
+
+.gwt-TextBox {
+}
+
+.gwt-TextBox-readonly {
+  color: #888;
+}
+
+.gwt-Tree {
+  background: white;
+}
+
+.gwt-Tree .gwt-TreeItem {
+}
+
+.gwt-Tree .gwt-TreeItem-selected {
+  background-color: #C3D9FF;
+}
+
+.gwt-StackPanel {
+}
+
+.gwt-StackPanel .gwt-StackPanelItem {
+  background-color: #C3D9FF;
+  cursor: pointer;
+  cursor: hand;
+}
+
+.gwt-StackPanel .gwt-StackPanelItem-selected {
+}
+
+.gwt-PushButton-up {
+  background-color: #C3D9FF;
+  padding: 2px;
+  border: 2px solid transparent;
+  border-color: #E8F1FF rgb(157, 174, 205) rgb(157, 174, 205) rgb(232, 241, 255);
+  cursor: pointer;
+  cursor: hand;
+}
+
+.gwt-PushButton-up-hovering {
+  background-color: #C3D9FF;
+  padding: 2px;
+  border: 2px solid transparent;
+  border-color: #E8F1FF rgb(157, 174, 205) rgb(157, 174, 205) rgb(232, 241, 255);
+  cursor: pointer;
+  cursor: hand;
+}
+
+.gwt-PushButton-down {
+  background-color: #C3D9FF;
+  padding: 2px;
+  border: 2px solid transparent;
+  border-color: #9DAECD rgb(232, 241, 255) rgb(232, 241, 255) rgb(157, 174, 205);
+  cursor: pointer;
+  cursor: hand;
+}
+
+.gwt-PushButton-down-hovering {
+  background-color: #C3D9FF;
+  padding: 2px;
+  border: 2px solid transparent;
+  border-color: #9DAECD rgb(232, 241, 255) rgb(232, 241, 255) rgb(157, 174, 205);
+  cursor: pointer;
+  cursor: hand;
+}
+
+.gwt-ToggleButton-up {
+  background-color: #C3D9FF;
+  padding: 2px;
+  border: 2px solid transparent;
+  border-color: #E8F1FF rgb(157, 174, 205) rgb(157, 174, 205) rgb(232, 241, 255);
+  cursor: pointer;
+  cursor: hand;
+}
+
+.gwt-ToggleButton-up-hovering {
+  background-color: #C3D9FF;
+  padding: 2px;
+  border: 2px solid transparent;
+  border-color: #E8F1FF rgb(157, 174, 205) rgb(157, 174, 205) rgb(232, 241, 255);
+  cursor: pointer;
+  cursor: hand;
+}
+
+.gwt-ToggleButton-down {
+  background-color: #C3D9FF;
+  padding: 2px;
+  background-color: #E8F1FF;
+  border: 2px solid transparent;
+  border-color: #9DAECD rgb(232, 241, 255) rgb(232, 241, 255) rgb(157, 174, 205);
+  cursor: pointer;
+  cursor: hand;
+}
+
+.gwt-ToggleButton-down-hovering {
+  background-color: #C3D9FF;
+  padding: 2px;
+  background-color: #E8F1FF;
+  border: 2px solid transparent;
+  border-color: #9DAECD rgb(232, 241, 255) rgb(232, 241, 255) rgb(157, 174, 205);
+  cursor: pointer;
+  cursor: hand;
+}
+
+.gwt-RichTextArea {
+  border: 1px solid black;
+  background-color: white;
+}
+
+.gwt-RichTextToolbar {
+  background-color: #C3D9FF;
+  padding: 2px;
+}
+
+.gwt-RichTextToolbar .gwt-PushButton-up {
+  margin-right: 2px;
+  border: 1px solid #C3D9FF;
+}
+
+.gwt-RichTextToolbar .gwt-PushButton-up-hovering {
+  margin-right: 2px;
+  border: 1px solid #C3D9FF;
+  border-color: #E8F1FF rgb(157, 174, 205) rgb(157, 174, 205) rgb(232, 241, 255);
+}
+
+.gwt-RichTextToolbar .gwt-PushButton-down {
+  margin-right: 2px;
+  border: 1px solid #C3D9FF;
+  border-color: #9DAECD rgb(232, 241, 255) rgb(232, 241, 255) rgb(157, 174, 205);
+}
+
+.gwt-RichTextToolbar .gwt-PushButton-down-hovering {
+  margin-right: 2px;
+  border: 1px solid #C3D9FF;
+  border-color: #9DAECD rgb(232, 241, 255) rgb(232, 241, 255) rgb(157, 174, 205);
+}
+
+.gwt-RichTextToolbar .gwt-ToggleButton-up {
+  margin-right: 2px;
+  border: 1px solid #C3D9FF;
+}
+
+.gwt-RichTextToolbar .gwt-ToggleButton-up-hovering {
+  margin-right: 2px;
+  border: 1px solid #C3D9FF;
+  border-color: #E8F1FF rgb(157, 174, 205) rgb(157, 174, 205) rgb(232, 241, 255);
+}
+
+.gwt-RichTextToolbar .gwt-ToggleButton-down {
+  margin-right: 2px;
+  background-color: #E8F1FF;
+  border: 1px solid #C3D9FF;
+  border-color: #9DAECD rgb(232, 241, 255) rgb(232, 241, 255) rgb(157, 174, 205);
+}
+
+.gwt-RichTextToolbar .gwt-ToggleButton-down-hovering {
+  margin-right: 2px;
+  background-color: #E8F1FF;
+  border: 1px solid #C3D9FF;
+  border-color: #9DAECD rgb(232, 241, 255) rgb(232, 241, 255) rgb(157, 174, 205);
+}
+
+.gwt-HorizontalSplitPanel {
+  border: 8px solid #C3D9FF;
+}
+
+.gwt-HorizontalSplitPanel .hsplitter {
+  background-color: #C3D9FF;
+  cursor: move;
+}
+
+.gwt-HorizontalSplitPanel .left {
+  background-color: #E8EEF7;
+}
+
+.gwt-VerticalSplitPanel {
+}
+
+.gwt-VerticalSplitPanel .splitter {
+  background-color: #C3D9FF;
+  height: 8px;
+  cursor: move;
+}
+
+.gwt-SuggestBoxPopup {
+  border: 2px solid #C3D9FF;
+}
+
+.gwt-SuggestBoxPopup .item {
+  padding: 2px;
+}
+
+.gwt-SuggestBoxPopup .item-selected {
+  background-color: #C3D9FF;
+  padding: 2px;
+}
+
+.ks-Sink {
+  width: 100%;
+  height: 24em;
+}
+
+.ks-Info {
+  color: white;
+  padding: 20px 10px 20px 40px;
+  margin-bottom: 10px;
+}
+
+.ks-List {
+}
+
+.ks-List .gwt-Image {
+  position: relative;
+  top: 8px;
+}
+
+.ks-List .ks-SinkItem a {
+  text-decoration: none;
+  color: white;
+}
+
+.ks-List .ks-SinkItem-selected a {
+  text-decoration: none;
+  color: white;
+}
+
+.ks-List .ks-FirstSinkItem a {
+  text-decoration: none;
+  color: white;
+}
+
+.ks-List .ks-FirstSinkItem-selected a {
+  text-decoration: none;
+  color: white;
+}
+
+.ks-List .ks-SinkItem {
+  background: #c6cab7;
+  padding: 4px;
+  padding-left: 16px;
+  padding-right: 16px;
+  margin-right: 3px;
+  border-bottom: 3px solid white;
+  cursor: pointer;
+  cursor: hand;
+}
+
+.ks-List .ks-SinkItem-selected {
+  background: #c6cab7;
+  padding: 4px;
+  padding-left: 16px;
+  padding-right: 16px;
+  margin-right: 3px;
+  padding-bottom: 7px;
+}
+
+.ks-List .ks-FirstSinkItem {
+  background: #c6cab7 url(images/corner.gif) no-repeat top left;
+  padding: 4px;
+  padding-left: 16px;
+  padding-right: 16px;
+  margin-right: 3px;
+  border-bottom: 3px solid white;
+  cursor: pointer;
+  cursor: hand;
+}
+
+.ks-List .ks-FirstSinkItem-selected {
+  background: #c3d9ff url(images/corner.gif) no-repeat top left;
+  padding: 4px;
+  padding-left: 16px;
+  padding-right: 16px;
+  margin-right: 3px;
+  padding-bottom: 7px;
+}
+
+.ks-images-Image {
+  margin: 8px;
+}
+
+.ks-images-Button {
+  margin: 8px;
+  cursor: pointer;
+  cursor: hand;
+}
+
+.ks-layouts {
+  margin: 8px;
+}
+
+.ks-layouts-Label {
+  background-color: #C3D9FF;
+  font-weight: bold;
+  margin-top: 1em;
+  padding: 2px 0px 2px 0px;
+  width: 100%;
+}
+
+.ks-layouts-Scroller {
+  height: 128px;
+  border: 2px solid #C3D9FF;
+  padding: 8px;
+  margin: 8px;
+}
+
+.ks-popups-Popup {
+  background-color: white;
+  border: 1px solid #87B3FF;
+  padding: 4px;
+}

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/prototype.js
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/prototype.js	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/prototype.js	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,2515 @@
+/*  Prototype JavaScript framework, version 1.5.0
+ *  (c) 2005-2007 Sam Stephenson
+ *
+ *  Prototype is freely distributable under the terms of an MIT-style license.
+ *  For details, see the Prototype web site: http://prototype.conio.net/
+ *
+/*--------------------------------------------------------------------------*/
+
+var Prototype = {
+  Version: '1.5.0',
+  BrowserFeatures: {
+    XPath: !!document.evaluate
+  },
+
+  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
+  emptyFunction: function() {},
+  K: function(x) { return x }
+}
+
+var Class = {
+  create: function() {
+    return function() {
+      this.initialize.apply(this, arguments);
+    }
+  }
+}
+
+var Abstract = new Object();
+
+Object.extend = function(destination, source) {
+  for (var property in source) {
+    destination[property] = source[property];
+  }
+  return destination;
+}
+
+Object.extend(Object, {
+  inspect: function(object) {
+    try {
+      if (object === undefined) return 'undefined';
+      if (object === null) return 'null';
+      return object.inspect ? object.inspect() : object.toString();
+    } catch (e) {
+      if (e instanceof RangeError) return '...';
+      throw e;
+    }
+  },
+
+  keys: function(object) {
+    var keys = [];
+    for (var property in object)
+      keys.push(property);
+    return keys;
+  },
+
+  values: function(object) {
+    var values = [];
+    for (var property in object)
+      values.push(object[property]);
+    return values;
+  },
+
+  clone: function(object) {
+    return Object.extend({}, object);
+  }
+});
+
+Function.prototype.bind = function() {
+  var __method = this, args = $A(arguments), object = args.shift();
+  return function() {
+    return __method.apply(object, args.concat($A(arguments)));
+  }
+}
+
+Function.prototype.bindAsEventListener = function(object) {
+  var __method = this, args = $A(arguments), object = args.shift();
+  return function(event) {
+    return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
+  }
+}
+
+Object.extend(Number.prototype, {
+  toColorPart: function() {
+    var digits = this.toString(16);
+    if (this < 16) return '0' + digits;
+    return digits;
+  },
+
+  succ: function() {
+    return this + 1;
+  },
+
+  times: function(iterator) {
+    $R(0, this, true).each(iterator);
+    return this;
+  }
+});
+
+var Try = {
+  these: function() {
+    var returnValue;
+
+    for (var i = 0, length = arguments.length; i < length; i++) {
+      var lambda = arguments[i];
+      try {
+        returnValue = lambda();
+        break;
+      } catch (e) {}
+    }
+
+    return returnValue;
+  }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var PeriodicalExecuter = Class.create();
+PeriodicalExecuter.prototype = {
+  initialize: function(callback, frequency) {
+    this.callback = callback;
+    this.frequency = frequency;
+    this.currentlyExecuting = false;
+
+    this.registerCallback();
+  },
+
+  registerCallback: function() {
+    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  stop: function() {
+    if (!this.timer) return;
+    clearInterval(this.timer);
+    this.timer = null;
+  },
+
+  onTimerEvent: function() {
+    if (!this.currentlyExecuting) {
+      try {
+        this.currentlyExecuting = true;
+        this.callback(this);
+      } finally {
+        this.currentlyExecuting = false;
+      }
+    }
+  }
+}
+String.interpret = function(value){
+  return value == null ? '' : String(value);
+}
+
+Object.extend(String.prototype, {
+  gsub: function(pattern, replacement) {
+    var result = '', source = this, match;
+    replacement = arguments.callee.prepareReplacement(replacement);
+
+    while (source.length > 0) {
+      if (match = source.match(pattern)) {
+        result += source.slice(0, match.index);
+        result += String.interpret(replacement(match));
+        source  = source.slice(match.index + match[0].length);
+      } else {
+        result += source, source = '';
+      }
+    }
+    return result;
+  },
+
+  sub: function(pattern, replacement, count) {
+    replacement = this.gsub.prepareReplacement(replacement);
+    count = count === undefined ? 1 : count;
+
+    return this.gsub(pattern, function(match) {
+      if (--count < 0) return match[0];
+      return replacement(match);
+    });
+  },
+
+  scan: function(pattern, iterator) {
+    this.gsub(pattern, iterator);
+    return this;
+  },
+
+  truncate: function(length, truncation) {
+    length = length || 30;
+    truncation = truncation === undefined ? '...' : truncation;
+    return this.length > length ?
+      this.slice(0, length - truncation.length) + truncation : this;
+  },
+
+  strip: function() {
+    return this.replace(/^\s+/, '').replace(/\s+$/, '');
+  },
+
+  stripTags: function() {
+    return this.replace(/<\/?[^>]+>/gi, '');
+  },
+
+  stripScripts: function() {
+    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+  },
+
+  extractScripts: function() {
+    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
+    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+    return (this.match(matchAll) || []).map(function(scriptTag) {
+      return (scriptTag.match(matchOne) || ['', ''])[1];
+    });
+  },
+
+  evalScripts: function() {
+    return this.extractScripts().map(function(script) { return eval(script) });
+  },
+
+  escapeHTML: function() {
+    var div = document.createElement('div');
+    var text = document.createTextNode(this);
+    div.appendChild(text);
+    return div.innerHTML;
+  },
+
+  unescapeHTML: function() {
+    var div = document.createElement('div');
+    div.innerHTML = this.stripTags();
+    return div.childNodes[0] ? (div.childNodes.length > 1 ?
+      $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) :
+      div.childNodes[0].nodeValue) : '';
+  },
+
+  toQueryParams: function(separator) {
+    var match = this.strip().match(/([^?#]*)(#.*)?$/);
+    if (!match) return {};
+
+    return match[1].split(separator || '&').inject({}, function(hash, pair) {
+      if ((pair = pair.split('='))[0]) {
+        var name = decodeURIComponent(pair[0]);
+        var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
+
+        if (hash[name] !== undefined) {
+          if (hash[name].constructor != Array)
+            hash[name] = [hash[name]];
+          if (value) hash[name].push(value);
+        }
+        else hash[name] = value;
+      }
+      return hash;
+    });
+  },
+
+  toArray: function() {
+    return this.split('');
+  },
+
+  succ: function() {
+    return this.slice(0, this.length - 1) +
+      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+  },
+
+  camelize: function() {
+    var parts = this.split('-'), len = parts.length;
+    if (len == 1) return parts[0];
+
+    var camelized = this.charAt(0) == '-'
+      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+      : parts[0];
+
+    for (var i = 1; i < len; i++)
+      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+
+    return camelized;
+  },
+
+  capitalize: function(){
+    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+  },
+
+  underscore: function() {
+    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
+  },
+
+  dasherize: function() {
+    return this.gsub(/_/,'-');
+  },
+
+  inspect: function(useDoubleQuotes) {
+    var escapedString = this.replace(/\\/g, '\\\\');
+    if (useDoubleQuotes)
+      return '"' + escapedString.replace(/"/g, '\\"') + '"';
+    else
+      return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+  }
+});
+
+String.prototype.gsub.prepareReplacement = function(replacement) {
+  if (typeof replacement == 'function') return replacement;
+  var template = new Template(replacement);
+  return function(match) { return template.evaluate(match) };
+}
+
+String.prototype.parseQuery = String.prototype.toQueryParams;
+
+var Template = Class.create();
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+Template.prototype = {
+  initialize: function(template, pattern) {
+    this.template = template.toString();
+    this.pattern  = pattern || Template.Pattern;
+  },
+
+  evaluate: function(object) {
+    return this.template.gsub(this.pattern, function(match) {
+      var before = match[1];
+      if (before == '\\') return match[2];
+      return before + String.interpret(object[match[3]]);
+    });
+  }
+}
+
+var $break    = new Object();
+var $continue = new Object();
+
+var Enumerable = {
+  each: function(iterator) {
+    var index = 0;
+    try {
+      this._each(function(value) {
+        try {
+          iterator(value, index++);
+        } catch (e) {
+          if (e != $continue) throw e;
+        }
+      });
+    } catch (e) {
+      if (e != $break) throw e;
+    }
+    return this;
+  },
+
+  eachSlice: function(number, iterator) {
+    var index = -number, slices = [], array = this.toArray();
+    while ((index += number) < array.length)
+      slices.push(array.slice(index, index+number));
+    return slices.map(iterator);
+  },
+
+  all: function(iterator) {
+    var result = true;
+    this.each(function(value, index) {
+      result = result && !!(iterator || Prototype.K)(value, index);
+      if (!result) throw $break;
+    });
+    return result;
+  },
+
+  any: function(iterator) {
+    var result = false;
+    this.each(function(value, index) {
+      if (result = !!(iterator || Prototype.K)(value, index))
+        throw $break;
+    });
+    return result;
+  },
+
+  collect: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      results.push((iterator || Prototype.K)(value, index));
+    });
+    return results;
+  },
+
+  detect: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      if (iterator(value, index)) {
+        result = value;
+        throw $break;
+      }
+    });
+    return result;
+  },
+
+  findAll: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      if (iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  grep: function(pattern, iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      var stringValue = value.toString();
+      if (stringValue.match(pattern))
+        results.push((iterator || Prototype.K)(value, index));
+    })
+    return results;
+  },
+
+  include: function(object) {
+    var found = false;
+    this.each(function(value) {
+      if (value == object) {
+        found = true;
+        throw $break;
+      }
+    });
+    return found;
+  },
+
+  inGroupsOf: function(number, fillWith) {
+    fillWith = fillWith === undefined ? null : fillWith;
+    return this.eachSlice(number, function(slice) {
+      while(slice.length < number) slice.push(fillWith);
+      return slice;
+    });
+  },
+
+  inject: function(memo, iterator) {
+    this.each(function(value, index) {
+      memo = iterator(memo, value, index);
+    });
+    return memo;
+  },
+
+  invoke: function(method) {
+    var args = $A(arguments).slice(1);
+    return this.map(function(value) {
+      return value[method].apply(value, args);
+    });
+  },
+
+  max: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      value = (iterator || Prototype.K)(value, index);
+      if (result == undefined || value >= result)
+        result = value;
+    });
+    return result;
+  },
+
+  min: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      value = (iterator || Prototype.K)(value, index);
+      if (result == undefined || value < result)
+        result = value;
+    });
+    return result;
+  },
+
+  partition: function(iterator) {
+    var trues = [], falses = [];
+    this.each(function(value, index) {
+      ((iterator || Prototype.K)(value, index) ?
+        trues : falses).push(value);
+    });
+    return [trues, falses];
+  },
+
+  pluck: function(property) {
+    var results = [];
+    this.each(function(value, index) {
+      results.push(value[property]);
+    });
+    return results;
+  },
+
+  reject: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      if (!iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  sortBy: function(iterator) {
+    return this.map(function(value, index) {
+      return {value: value, criteria: iterator(value, index)};
+    }).sort(function(left, right) {
+      var a = left.criteria, b = right.criteria;
+      return a < b ? -1 : a > b ? 1 : 0;
+    }).pluck('value');
+  },
+
+  toArray: function() {
+    return this.map();
+  },
+
+  zip: function() {
+    var iterator = Prototype.K, args = $A(arguments);
+    if (typeof args.last() == 'function')
+      iterator = args.pop();
+
+    var collections = [this].concat(args).map($A);
+    return this.map(function(value, index) {
+      return iterator(collections.pluck(index));
+    });
+  },
+
+  size: function() {
+    return this.toArray().length;
+  },
+
+  inspect: function() {
+    return '#<Enumerable:' + this.toArray().inspect() + '>';
+  }
+}
+
+Object.extend(Enumerable, {
+  map:     Enumerable.collect,
+  find:    Enumerable.detect,
+  select:  Enumerable.findAll,
+  member:  Enumerable.include,
+  entries: Enumerable.toArray
+});
+var $A = Array.from = function(iterable) {
+  if (!iterable) return [];
+  if (iterable.toArray) {
+    return iterable.toArray();
+  } else {
+    var results = [];
+    for (var i = 0, length = iterable.length; i < length; i++)
+      results.push(iterable[i]);
+    return results;
+  }
+}
+
+Object.extend(Array.prototype, Enumerable);
+
+if (!Array.prototype._reverse)
+  Array.prototype._reverse = Array.prototype.reverse;
+
+Object.extend(Array.prototype, {
+  _each: function(iterator) {
+    for (var i = 0, length = this.length; i < length; i++)
+      iterator(this[i]);
+  },
+
+  clear: function() {
+    this.length = 0;
+    return this;
+  },
+
+  first: function() {
+    return this[0];
+  },
+
+  last: function() {
+    return this[this.length - 1];
+  },
+
+  compact: function() {
+    return this.select(function(value) {
+      return value != null;
+    });
+  },
+
+  flatten: function() {
+    return this.inject([], function(array, value) {
+      return array.concat(value && value.constructor == Array ?
+        value.flatten() : [value]);
+    });
+  },
+
+  without: function() {
+    var values = $A(arguments);
+    return this.select(function(value) {
+      return !values.include(value);
+    });
+  },
+
+  indexOf: function(object) {
+    for (var i = 0, length = this.length; i < length; i++)
+      if (this[i] == object) return i;
+    return -1;
+  },
+
+  reverse: function(inline) {
+    return (inline !== false ? this : this.toArray())._reverse();
+  },
+
+  reduce: function() {
+    return this.length > 1 ? this : this[0];
+  },
+
+  uniq: function() {
+    return this.inject([], function(array, value) {
+      return array.include(value) ? array : array.concat([value]);
+    });
+  },
+
+  clone: function() {
+    return [].concat(this);
+  },
+
+  size: function() {
+    return this.length;
+  },
+
+  inspect: function() {
+    return '[' + this.map(Object.inspect).join(', ') + ']';
+  }
+});
+
+Array.prototype.toArray = Array.prototype.clone;
+
+function $w(string){
+  string = string.strip();
+  return string ? string.split(/\s+/) : [];
+}
+
+if(window.opera){
+  Array.prototype.concat = function(){
+    var array = [];
+    for(var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+    for(var i = 0, length = arguments.length; i < length; i++) {
+      if(arguments[i].constructor == Array) {
+        for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+          array.push(arguments[i][j]);
+      } else {
+        array.push(arguments[i]);
+      }
+    }
+    return array;
+  }
+}
+var Hash = function(obj) {
+  Object.extend(this, obj || {});
+};
+
+Object.extend(Hash, {
+  toQueryString: function(obj) {
+    var parts = [];
+
+	  this.prototype._each.call(obj, function(pair) {
+      if (!pair.key) return;
+
+      if (pair.value && pair.value.constructor == Array) {
+        var values = pair.value.compact();
+        if (values.length < 2) pair.value = values.reduce();
+        else {
+        	key = encodeURIComponent(pair.key);
+          values.each(function(value) {
+            value = value != undefined ? encodeURIComponent(value) : '';
+            parts.push(key + '=' + encodeURIComponent(value));
+          });
+          return;
+        }
+      }
+      if (pair.value == undefined) pair[1] = '';
+      parts.push(pair.map(encodeURIComponent).join('='));
+	  });
+
+    return parts.join('&');
+  }
+});
+
+Object.extend(Hash.prototype, Enumerable);
+Object.extend(Hash.prototype, {
+  _each: function(iterator) {
+    for (var key in this) {
+      var value = this[key];
+      if (value && value == Hash.prototype[key]) continue;
+
+      var pair = [key, value];
+      pair.key = key;
+      pair.value = value;
+      iterator(pair);
+    }
+  },
+
+  keys: function() {
+    return this.pluck('key');
+  },
+
+  values: function() {
+    return this.pluck('value');
+  },
+
+  merge: function(hash) {
+    return $H(hash).inject(this, function(mergedHash, pair) {
+      mergedHash[pair.key] = pair.value;
+      return mergedHash;
+    });
+  },
+
+  remove: function() {
+    var result;
+    for(var i = 0, length = arguments.length; i < length; i++) {
+      var value = this[arguments[i]];
+      if (value !== undefined){
+        if (result === undefined) result = value;
+        else {
+          if (result.constructor != Array) result = [result];
+          result.push(value)
+        }
+      }
+      delete this[arguments[i]];
+    }
+    return result;
+  },
+
+  toQueryString: function() {
+    return Hash.toQueryString(this);
+  },
+
+  inspect: function() {
+    return '#<Hash:{' + this.map(function(pair) {
+      return pair.map(Object.inspect).join(': ');
+    }).join(', ') + '}>';
+  }
+});
+
+function $H(object) {
+  if (object && object.constructor == Hash) return object;
+  return new Hash(object);
+};
+ObjectRange = Class.create();
+Object.extend(ObjectRange.prototype, Enumerable);
+Object.extend(ObjectRange.prototype, {
+  initialize: function(start, end, exclusive) {
+    this.start = start;
+    this.end = end;
+    this.exclusive = exclusive;
+  },
+
+  _each: function(iterator) {
+    var value = this.start;
+    while (this.include(value)) {
+      iterator(value);
+      value = value.succ();
+    }
+  },
+
+  include: function(value) {
+    if (value < this.start)
+      return false;
+    if (this.exclusive)
+      return value < this.end;
+    return value <= this.end;
+  }
+});
+
+var $R = function(start, end, exclusive) {
+  return new ObjectRange(start, end, exclusive);
+}
+
+var Ajax = {
+  getTransport: function() {
+    return Try.these(
+      function() {return new XMLHttpRequest()},
+      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
+    ) || false;
+  },
+
+  activeRequestCount: 0
+}
+
+Ajax.Responders = {
+  responders: [],
+
+  _each: function(iterator) {
+    this.responders._each(iterator);
+  },
+
+  register: function(responder) {
+    if (!this.include(responder))
+      this.responders.push(responder);
+  },
+
+  unregister: function(responder) {
+    this.responders = this.responders.without(responder);
+  },
+
+  dispatch: function(callback, request, transport, json) {
+    this.each(function(responder) {
+      if (typeof responder[callback] == 'function') {
+        try {
+          responder[callback].apply(responder, [request, transport, json]);
+        } catch (e) {}
+      }
+    });
+  }
+};
+
+Object.extend(Ajax.Responders, Enumerable);
+
+Ajax.Responders.register({
+  onCreate: function() {
+    Ajax.activeRequestCount++;
+  },
+  onComplete: function() {
+    Ajax.activeRequestCount--;
+  }
+});
+
+Ajax.Base = function() {};
+Ajax.Base.prototype = {
+  setOptions: function(options) {
+    this.options = {
+      method:       'post',
+      asynchronous: true,
+      contentType:  'application/x-www-form-urlencoded',
+      encoding:     'UTF-8',
+      parameters:   ''
+    }
+    Object.extend(this.options, options || {});
+
+    this.options.method = this.options.method.toLowerCase();
+    if (typeof this.options.parameters == 'string')
+      this.options.parameters = this.options.parameters.toQueryParams();
+  }
+}
+
+Ajax.Request = Class.create();
+Ajax.Request.Events =
+  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
+  _complete: false,
+
+  initialize: function(url, options) {
+    this.transport = Ajax.getTransport();
+    this.setOptions(options);
+    this.request(url);
+  },
+
+  request: function(url) {
+    this.url = url;
+    this.method = this.options.method;
+    var params = this.options.parameters;
+
+    if (!['get', 'post'].include(this.method)) {
+      // simulate other verbs over post
+      params['_method'] = this.method;
+      this.method = 'post';
+    }
+
+    params = Hash.toQueryString(params);
+    if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='
+
+    // when GET, append parameters to URL
+    if (this.method == 'get' && params)
+      this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params;
+
+    try {
+      Ajax.Responders.dispatch('onCreate', this, this.transport);
+
+      this.transport.open(this.method.toUpperCase(), this.url,
+        this.options.asynchronous);
+
+      if (this.options.asynchronous)
+        setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
+
+      this.transport.onreadystatechange = this.onStateChange.bind(this);
+      this.setRequestHeaders();
+
+      var body = this.method == 'post' ? (this.options.postBody || params) : null;
+
+      this.transport.send(body);
+
+      /* Force Firefox to handle ready state 4 for synchronous requests */
+      if (!this.options.asynchronous && this.transport.overrideMimeType)
+        this.onStateChange();
+
+    }
+    catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  onStateChange: function() {
+    var readyState = this.transport.readyState;
+    if (readyState > 1 && !((readyState == 4) && this._complete))
+      this.respondToReadyState(this.transport.readyState);
+  },
+
+  setRequestHeaders: function() {
+    var headers = {
+      'X-Requested-With': 'XMLHttpRequest',
+      'X-Prototype-Version': Prototype.Version,
+      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+    };
+
+    if (this.method == 'post') {
+      headers['Content-type'] = this.options.contentType +
+        (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+      /* Force "Connection: close" for older Mozilla browsers to work
+       * around a bug where XMLHttpRequest sends an incorrect
+       * Content-length header. See Mozilla Bugzilla #246651.
+       */
+      if (this.transport.overrideMimeType &&
+          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+            headers['Connection'] = 'close';
+    }
+
+    // user-defined headers
+    if (typeof this.options.requestHeaders == 'object') {
+      var extras = this.options.requestHeaders;
+
+      if (typeof extras.push == 'function')
+        for (var i = 0, length = extras.length; i < length; i += 2)
+          headers[extras[i]] = extras[i+1];
+      else
+        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+    }
+
+    for (var name in headers)
+      this.transport.setRequestHeader(name, headers[name]);
+  },
+
+  success: function() {
+    return !this.transport.status
+        || (this.transport.status >= 200 && this.transport.status < 300);
+  },
+
+  respondToReadyState: function(readyState) {
+    var state = Ajax.Request.Events[readyState];
+    var transport = this.transport, json = this.evalJSON();
+
+    if (state == 'Complete') {
+      try {
+        this._complete = true;
+        (this.options['on' + this.transport.status]
+         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+         || Prototype.emptyFunction)(transport, json);
+      } catch (e) {
+        this.dispatchException(e);
+      }
+
+      if ((this.getHeader('Content-type') || 'text/javascript').strip().
+        match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
+          this.evalResponse();
+    }
+
+    try {
+      (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
+      Ajax.Responders.dispatch('on' + state, this, transport, json);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+
+    if (state == 'Complete') {
+      // avoid memory leak in MSIE: clean up
+      this.transport.onreadystatechange = Prototype.emptyFunction;
+    }
+  },
+
+  getHeader: function(name) {
+    try {
+      return this.transport.getResponseHeader(name);
+    } catch (e) { return null }
+  },
+
+  evalJSON: function() {
+    try {
+      var json = this.getHeader('X-JSON');
+      return json ? eval('(' + json + ')') : null;
+    } catch (e) { return null }
+  },
+
+  evalResponse: function() {
+    try {
+      return eval(this.transport.responseText);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  dispatchException: function(exception) {
+    (this.options.onException || Prototype.emptyFunction)(this, exception);
+    Ajax.Responders.dispatch('onException', this, exception);
+  }
+});
+
+Ajax.Updater = Class.create();
+
+Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
+  initialize: function(container, url, options) {
+    this.container = {
+      success: (container.success || container),
+      failure: (container.failure || (container.success ? null : container))
+    }
+
+    this.transport = Ajax.getTransport();
+    this.setOptions(options);
+
+    var onComplete = this.options.onComplete || Prototype.emptyFunction;
+    this.options.onComplete = (function(transport, param) {
+      this.updateContent();
+      onComplete(transport, param);
+    }).bind(this);
+
+    this.request(url);
+  },
+
+  updateContent: function() {
+    var receiver = this.container[this.success() ? 'success' : 'failure'];
+    var response = this.transport.responseText;
+
+    if (!this.options.evalScripts) response = response.stripScripts();
+
+    if (receiver = $(receiver)) {
+      if (this.options.insertion)
+        new this.options.insertion(receiver, response);
+      else
+        receiver.update(response);
+    }
+
+    if (this.success()) {
+      if (this.onComplete)
+        setTimeout(this.onComplete.bind(this), 10);
+    }
+  }
+});
+
+Ajax.PeriodicalUpdater = Class.create();
+Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
+  initialize: function(container, url, options) {
+    this.setOptions(options);
+    this.onComplete = this.options.onComplete;
+
+    this.frequency = (this.options.frequency || 2);
+    this.decay = (this.options.decay || 1);
+
+    this.updater = {};
+    this.container = container;
+    this.url = url;
+
+    this.start();
+  },
+
+  start: function() {
+    this.options.onComplete = this.updateComplete.bind(this);
+    this.onTimerEvent();
+  },
+
+  stop: function() {
+    this.updater.options.onComplete = undefined;
+    clearTimeout(this.timer);
+    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+  },
+
+  updateComplete: function(request) {
+    if (this.options.decay) {
+      this.decay = (request.responseText == this.lastText ?
+        this.decay * this.options.decay : 1);
+
+      this.lastText = request.responseText;
+    }
+    this.timer = setTimeout(this.onTimerEvent.bind(this),
+      this.decay * this.frequency * 1000);
+  },
+
+  onTimerEvent: function() {
+    this.updater = new Ajax.Updater(this.container, this.url, this.options);
+  }
+});
+function $(element) {
+  if (arguments.length > 1) {
+    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+      elements.push($(arguments[i]));
+    return elements;
+  }
+  if (typeof element == 'string')
+    element = document.getElementById(element);
+  return Element.extend(element);
+}
+
+if (Prototype.BrowserFeatures.XPath) {
+  document._getElementsByXPath = function(expression, parentElement) {
+    var results = [];
+    var query = document.evaluate(expression, $(parentElement) || document,
+      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+    for (var i = 0, length = query.snapshotLength; i < length; i++)
+      results.push(query.snapshotItem(i));
+    return results;
+  };
+}
+
+document.getElementsByClassName = function(className, parentElement) {
+  if (Prototype.BrowserFeatures.XPath) {
+    var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
+    return document._getElementsByXPath(q, parentElement);
+  } else {
+    var children = ($(parentElement) || document.body).getElementsByTagName('*');
+    var elements = [], child;
+    for (var i = 0, length = children.length; i < length; i++) {
+      child = children[i];
+      if (Element.hasClassName(child, className))
+        elements.push(Element.extend(child));
+    }
+    return elements;
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Element)
+  var Element = new Object();
+
+Element.extend = function(element) {
+  if (!element || _nativeExtensions || element.nodeType == 3) return element;
+
+  if (!element._extended && element.tagName && element != window) {
+    var methods = Object.clone(Element.Methods), cache = Element.extend.cache;
+
+    if (element.tagName == 'FORM')
+      Object.extend(methods, Form.Methods);
+    if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName))
+      Object.extend(methods, Form.Element.Methods);
+
+    Object.extend(methods, Element.Methods.Simulated);
+
+    for (var property in methods) {
+      var value = methods[property];
+      if (typeof value == 'function' && !(property in element))
+        element[property] = cache.findOrStore(value);
+    }
+  }
+
+  element._extended = true;
+  return element;
+};
+
+Element.extend.cache = {
+  findOrStore: function(value) {
+    return this[value] = this[value] || function() {
+      return value.apply(null, [this].concat($A(arguments)));
+    }
+  }
+};
+
+Element.Methods = {
+  visible: function(element) {
+    return $(element).style.display != 'none';
+  },
+
+  toggle: function(element) {
+    element = $(element);
+    Element[Element.visible(element) ? 'hide' : 'show'](element);
+    return element;
+  },
+
+  hide: function(element) {
+    $(element).style.display = 'none';
+    return element;
+  },
+
+  show: function(element) {
+    $(element).style.display = '';
+    return element;
+  },
+
+  remove: function(element) {
+    element = $(element);
+    element.parentNode.removeChild(element);
+    return element;
+  },
+
+  update: function(element, html) {
+    html = typeof html == 'undefined' ? '' : html.toString();
+    $(element).innerHTML = html.stripScripts();
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  },
+
+  replace: function(element, html) {
+    element = $(element);
+    html = typeof html == 'undefined' ? '' : html.toString();
+    if (element.outerHTML) {
+      element.outerHTML = html.stripScripts();
+    } else {
+      var range = element.ownerDocument.createRange();
+      range.selectNodeContents(element);
+      element.parentNode.replaceChild(
+        range.createContextualFragment(html.stripScripts()), element);
+    }
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  },
+
+  inspect: function(element) {
+    element = $(element);
+    var result = '<' + element.tagName.toLowerCase();
+    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+      var property = pair.first(), attribute = pair.last();
+      var value = (element[property] || '').toString();
+      if (value) result += ' ' + attribute + '=' + value.inspect(true);
+    });
+    return result + '>';
+  },
+
+  recursivelyCollect: function(element, property) {
+    element = $(element);
+    var elements = [];
+    while (element = element[property])
+      if (element.nodeType == 1)
+        elements.push(Element.extend(element));
+    return elements;
+  },
+
+  ancestors: function(element) {
+    return $(element).recursivelyCollect('parentNode');
+  },
+
+  descendants: function(element) {
+    return $A($(element).getElementsByTagName('*'));
+  },
+
+  immediateDescendants: function(element) {
+    if (!(element = $(element).firstChild)) return [];
+    while (element && element.nodeType != 1) element = element.nextSibling;
+    if (element) return [element].concat($(element).nextSiblings());
+    return [];
+  },
+
+  previousSiblings: function(element) {
+    return $(element).recursivelyCollect('previousSibling');
+  },
+
+  nextSiblings: function(element) {
+    return $(element).recursivelyCollect('nextSibling');
+  },
+
+  siblings: function(element) {
+    element = $(element);
+    return element.previousSiblings().reverse().concat(element.nextSiblings());
+  },
+
+  match: function(element, selector) {
+    if (typeof selector == 'string')
+      selector = new Selector(selector);
+    return selector.match($(element));
+  },
+
+  up: function(element, expression, index) {
+    return Selector.findElement($(element).ancestors(), expression, index);
+  },
+
+  down: function(element, expression, index) {
+    return Selector.findElement($(element).descendants(), expression, index);
+  },
+
+  previous: function(element, expression, index) {
+    return Selector.findElement($(element).previousSiblings(), expression, index);
+  },
+
+  next: function(element, expression, index) {
+    return Selector.findElement($(element).nextSiblings(), expression, index);
+  },
+
+  getElementsBySelector: function() {
+    var args = $A(arguments), element = $(args.shift());
+    return Selector.findChildElements(element, args);
+  },
+
+  getElementsByClassName: function(element, className) {
+    return document.getElementsByClassName(className, element);
+  },
+
+  readAttribute: function(element, name) {
+    element = $(element);
+    if (document.all && !window.opera) {
+      var t = Element._attributeTranslations;
+      if (t.values[name]) return t.values[name](element, name);
+      if (t.names[name])  name = t.names[name];
+      var attribute = element.attributes[name];
+      if(attribute) return attribute.nodeValue;
+    }
+    return element.getAttribute(name);
+  },
+
+  getHeight: function(element) {
+    return $(element).getDimensions().height;
+  },
+
+  getWidth: function(element) {
+    return $(element).getDimensions().width;
+  },
+
+  classNames: function(element) {
+    return new Element.ClassNames(element);
+  },
+
+  hasClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    var elementClassName = element.className;
+    if (elementClassName.length == 0) return false;
+    if (elementClassName == className ||
+        elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+      return true;
+    return false;
+  },
+
+  addClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element).add(className);
+    return element;
+  },
+
+  removeClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element).remove(className);
+    return element;
+  },
+
+  toggleClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
+    return element;
+  },
+
+  observe: function() {
+    Event.observe.apply(Event, arguments);
+    return $A(arguments).first();
+  },
+
+  stopObserving: function() {
+    Event.stopObserving.apply(Event, arguments);
+    return $A(arguments).first();
+  },
+
+  // removes whitespace-only text node children
+  cleanWhitespace: function(element) {
+    element = $(element);
+    var node = element.firstChild;
+    while (node) {
+      var nextNode = node.nextSibling;
+      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+        element.removeChild(node);
+      node = nextNode;
+    }
+    return element;
+  },
+
+  empty: function(element) {
+    return $(element).innerHTML.match(/^\s*$/);
+  },
+
+  descendantOf: function(element, ancestor) {
+    element = $(element), ancestor = $(ancestor);
+    while (element = element.parentNode)
+      if (element == ancestor) return true;
+    return false;
+  },
+
+  scrollTo: function(element) {
+    element = $(element);
+    var pos = Position.cumulativeOffset(element);
+    window.scrollTo(pos[0], pos[1]);
+    return element;
+  },
+
+  getStyle: function(element, style) {
+    element = $(element);
+    if (['float','cssFloat'].include(style))
+      style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat');
+    style = style.camelize();
+    var value = element.style[style];
+    if (!value) {
+      if (document.defaultView && document.defaultView.getComputedStyle) {
+        var css = document.defaultView.getComputedStyle(element, null);
+        value = css ? css[style] : null;
+      } else if (element.currentStyle) {
+        value = element.currentStyle[style];
+      }
+    }
+
+    if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none'))
+      value = element['offset'+style.capitalize()] + 'px';
+
+    if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
+      if (Element.getStyle(element, 'position') == 'static') value = 'auto';
+    if(style == 'opacity') {
+      if(value) return parseFloat(value);
+      if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+        if(value[1]) return parseFloat(value[1]) / 100;
+      return 1.0;
+    }
+    return value == 'auto' ? null : value;
+  },
+
+  setStyle: function(element, style) {
+    element = $(element);
+    for (var name in style) {
+      var value = style[name];
+      if(name == 'opacity') {
+        if (value == 1) {
+          value = (/Gecko/.test(navigator.userAgent) &&
+            !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0;
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+        } else if(value === '') {
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+        } else {
+          if(value < 0.00001) value = 0;
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
+              'alpha(opacity='+value*100+')';
+        }
+      } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
+      element.style[name.camelize()] = value;
+    }
+    return element;
+  },
+
+  getDimensions: function(element) {
+    element = $(element);
+    var display = $(element).getStyle('display');
+    if (display != 'none' && display != null) // Safari bug
+      return {width: element.offsetWidth, height: element.offsetHeight};
+
+    // All *Width and *Height properties give 0 on elements with display none,
+    // so enable the element temporarily
+    var els = element.style;
+    var originalVisibility = els.visibility;
+    var originalPosition = els.position;
+    var originalDisplay = els.display;
+    els.visibility = 'hidden';
+    els.position = 'absolute';
+    els.display = 'block';
+    var originalWidth = element.clientWidth;
+    var originalHeight = element.clientHeight;
+    els.display = originalDisplay;
+    els.position = originalPosition;
+    els.visibility = originalVisibility;
+    return {width: originalWidth, height: originalHeight};
+  },
+
+  makePositioned: function(element) {
+    element = $(element);
+    var pos = Element.getStyle(element, 'position');
+    if (pos == 'static' || !pos) {
+      element._madePositioned = true;
+      element.style.position = 'relative';
+      // Opera returns the offset relative to the positioning context, when an
+      // element is position relative but top and left have not been defined
+      if (window.opera) {
+        element.style.top = 0;
+        element.style.left = 0;
+      }
+    }
+    return element;
+  },
+
+  undoPositioned: function(element) {
+    element = $(element);
+    if (element._madePositioned) {
+      element._madePositioned = undefined;
+      element.style.position =
+        element.style.top =
+        element.style.left =
+        element.style.bottom =
+        element.style.right = '';
+    }
+    return element;
+  },
+
+  makeClipping: function(element) {
+    element = $(element);
+    if (element._overflow) return element;
+    element._overflow = element.style.overflow || 'auto';
+    if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
+      element.style.overflow = 'hidden';
+    return element;
+  },
+
+  undoClipping: function(element) {
+    element = $(element);
+    if (!element._overflow) return element;
+    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+    element._overflow = null;
+    return element;
+  }
+};
+
+Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf});
+
+Element._attributeTranslations = {};
+
+Element._attributeTranslations.names = {
+  colspan:   "colSpan",
+  rowspan:   "rowSpan",
+  valign:    "vAlign",
+  datetime:  "dateTime",
+  accesskey: "accessKey",
+  tabindex:  "tabIndex",
+  enctype:   "encType",
+  maxlength: "maxLength",
+  readonly:  "readOnly",
+  longdesc:  "longDesc"
+};
+
+Element._attributeTranslations.values = {
+  _getAttr: function(element, attribute) {
+    return element.getAttribute(attribute, 2);
+  },
+
+  _flag: function(element, attribute) {
+    return $(element).hasAttribute(attribute) ? attribute : null;
+  },
+
+  style: function(element) {
+    return element.style.cssText.toLowerCase();
+  },
+
+  title: function(element) {
+    var node = element.getAttributeNode('title');
+    return node.specified ? node.nodeValue : null;
+  }
+};
+
+Object.extend(Element._attributeTranslations.values, {
+  href: Element._attributeTranslations.values._getAttr,
+  src:  Element._attributeTranslations.values._getAttr,
+  disabled: Element._attributeTranslations.values._flag,
+  checked:  Element._attributeTranslations.values._flag,
+  readonly: Element._attributeTranslations.values._flag,
+  multiple: Element._attributeTranslations.values._flag
+});
+
+Element.Methods.Simulated = {
+  hasAttribute: function(element, attribute) {
+    var t = Element._attributeTranslations;
+    attribute = t.names[attribute] || attribute;
+    return $(element).getAttributeNode(attribute).specified;
+  }
+};
+
+// IE is missing .innerHTML support for TABLE-related elements
+if (document.all && !window.opera){
+  Element.Methods.update = function(element, html) {
+    element = $(element);
+    html = typeof html == 'undefined' ? '' : html.toString();
+    var tagName = element.tagName.toUpperCase();
+    if (['THEAD','TBODY','TR','TD'].include(tagName)) {
+      var div = document.createElement('div');
+      switch (tagName) {
+        case 'THEAD':
+        case 'TBODY':
+          div.innerHTML = '<table><tbody>' +  html.stripScripts() + '</tbody></table>';
+          depth = 2;
+          break;
+        case 'TR':
+          div.innerHTML = '<table><tbody><tr>' +  html.stripScripts() + '</tr></tbody></table>';
+          depth = 3;
+          break;
+        case 'TD':
+          div.innerHTML = '<table><tbody><tr><td>' +  html.stripScripts() + '</td></tr></tbody></table>';
+          depth = 4;
+      }
+      $A(element.childNodes).each(function(node){
+        element.removeChild(node)
+      });
+      depth.times(function(){ div = div.firstChild });
+
+      $A(div.childNodes).each(
+        function(node){ element.appendChild(node) });
+    } else {
+      element.innerHTML = html.stripScripts();
+    }
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  }
+};
+
+Object.extend(Element, Element.Methods);
+
+var _nativeExtensions = false;
+
+if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+  ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) {
+    var className = 'HTML' + tag + 'Element';
+    if(window[className]) return;
+    var klass = window[className] = {};
+    klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
+  });
+
+Element.addMethods = function(methods) {
+  Object.extend(Element.Methods, methods || {});
+
+  function copy(methods, destination, onlyIfAbsent) {
+    onlyIfAbsent = onlyIfAbsent || false;
+    var cache = Element.extend.cache;
+    for (var property in methods) {
+      var value = methods[property];
+      if (!onlyIfAbsent || !(property in destination))
+        destination[property] = cache.findOrStore(value);
+    }
+  }
+
+  if (typeof HTMLElement != 'undefined') {
+    copy(Element.Methods, HTMLElement.prototype);
+    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+    copy(Form.Methods, HTMLFormElement.prototype);
+    [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
+      copy(Form.Element.Methods, klass.prototype);
+    });
+    _nativeExtensions = true;
+  }
+}
+
+var Toggle = new Object();
+Toggle.display = Element.toggle;
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.Insertion = function(adjacency) {
+  this.adjacency = adjacency;
+}
+
+Abstract.Insertion.prototype = {
+  initialize: function(element, content) {
+    this.element = $(element);
+    this.content = content.stripScripts();
+
+    if (this.adjacency && this.element.insertAdjacentHTML) {
+      try {
+        this.element.insertAdjacentHTML(this.adjacency, this.content);
+      } catch (e) {
+        var tagName = this.element.tagName.toUpperCase();
+        if (['TBODY', 'TR'].include(tagName)) {
+          this.insertContent(this.contentFromAnonymousTable());
+        } else {
+          throw e;
+        }
+      }
+    } else {
+      this.range = this.element.ownerDocument.createRange();
+      if (this.initializeRange) this.initializeRange();
+      this.insertContent([this.range.createContextualFragment(this.content)]);
+    }
+
+    setTimeout(function() {content.evalScripts()}, 10);
+  },
+
+  contentFromAnonymousTable: function() {
+    var div = document.createElement('div');
+    div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
+    return $A(div.childNodes[0].childNodes[0].childNodes);
+  }
+}
+
+var Insertion = new Object();
+
+Insertion.Before = Class.create();
+Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
+  initializeRange: function() {
+    this.range.setStartBefore(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.parentNode.insertBefore(fragment, this.element);
+    }).bind(this));
+  }
+});
+
+Insertion.Top = Class.create();
+Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
+  initializeRange: function() {
+    this.range.selectNodeContents(this.element);
+    this.range.collapse(true);
+  },
+
+  insertContent: function(fragments) {
+    fragments.reverse(false).each((function(fragment) {
+      this.element.insertBefore(fragment, this.element.firstChild);
+    }).bind(this));
+  }
+});
+
+Insertion.Bottom = Class.create();
+Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
+  initializeRange: function() {
+    this.range.selectNodeContents(this.element);
+    this.range.collapse(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.appendChild(fragment);
+    }).bind(this));
+  }
+});
+
+Insertion.After = Class.create();
+Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
+  initializeRange: function() {
+    this.range.setStartAfter(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.parentNode.insertBefore(fragment,
+        this.element.nextSibling);
+    }).bind(this));
+  }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Element.ClassNames = Class.create();
+Element.ClassNames.prototype = {
+  initialize: function(element) {
+    this.element = $(element);
+  },
+
+  _each: function(iterator) {
+    this.element.className.split(/\s+/).select(function(name) {
+      return name.length > 0;
+    })._each(iterator);
+  },
+
+  set: function(className) {
+    this.element.className = className;
+  },
+
+  add: function(classNameToAdd) {
+    if (this.include(classNameToAdd)) return;
+    this.set($A(this).concat(classNameToAdd).join(' '));
+  },
+
+  remove: function(classNameToRemove) {
+    if (!this.include(classNameToRemove)) return;
+    this.set($A(this).without(classNameToRemove).join(' '));
+  },
+
+  toString: function() {
+    return $A(this).join(' ');
+  }
+};
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+var Selector = Class.create();
+Selector.prototype = {
+  initialize: function(expression) {
+    this.params = {classNames: []};
+    this.expression = expression.toString().strip();
+    this.parseExpression();
+    this.compileMatcher();
+  },
+
+  parseExpression: function() {
+    function abort(message) { throw 'Parse error in selector: ' + message; }
+
+    if (this.expression == '')  abort('empty expression');
+
+    var params = this.params, expr = this.expression, match, modifier, clause, rest;
+    while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
+      params.attributes = params.attributes || [];
+      params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
+      expr = match[1];
+    }
+
+    if (expr == '*') return this.params.wildcard = true;
+
+    while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) {
+      modifier = match[1], clause = match[2], rest = match[3];
+      switch (modifier) {
+        case '#':       params.id = clause; break;
+        case '.':       params.classNames.push(clause); break;
+        case '':
+        case undefined: params.tagName = clause.toUpperCase(); break;
+        default:        abort(expr.inspect());
+      }
+      expr = rest;
+    }
+
+    if (expr.length > 0) abort(expr.inspect());
+  },
+
+  buildMatchExpression: function() {
+    var params = this.params, conditions = [], clause;
+
+    if (params.wildcard)
+      conditions.push('true');
+    if (clause = params.id)
+      conditions.push('element.readAttribute("id") == ' + clause.inspect());
+    if (clause = params.tagName)
+      conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
+    if ((clause = params.classNames).length > 0)
+      for (var i = 0, length = clause.length; i < length; i++)
+        conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
+    if (clause = params.attributes) {
+      clause.each(function(attribute) {
+        var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
+        var splitValueBy = function(delimiter) {
+          return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
+        }
+
+        switch (attribute.operator) {
+          case '=':       conditions.push(value + ' == ' + attribute.value.inspect()); break;
+          case '~=':      conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break;
+          case '|=':      conditions.push(
+                            splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect()
+                          ); break;
+          case '!=':      conditions.push(value + ' != ' + attribute.value.inspect()); break;
+          case '':
+          case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break;
+          default:        throw 'Unknown operator ' + attribute.operator + ' in selector';
+        }
+      });
+    }
+
+    return conditions.join(' && ');
+  },
+
+  compileMatcher: function() {
+    this.match = new Function('element', 'if (!element.tagName) return false; \
+      element = $(element); \
+      return ' + this.buildMatchExpression());
+  },
+
+  findElements: function(scope) {
+    var element;
+
+    if (element = $(this.params.id))
+      if (this.match(element))
+        if (!scope || Element.childOf(element, scope))
+          return [element];
+
+    scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
+
+    var results = [];
+    for (var i = 0, length = scope.length; i < length; i++)
+      if (this.match(element = scope[i]))
+        results.push(Element.extend(element));
+
+    return results;
+  },
+
+  toString: function() {
+    return this.expression;
+  }
+}
+
+Object.extend(Selector, {
+  matchElements: function(elements, expression) {
+    var selector = new Selector(expression);
+    return elements.select(selector.match.bind(selector)).map(Element.extend);
+  },
+
+  findElement: function(elements, expression, index) {
+    if (typeof expression == 'number') index = expression, expression = false;
+    return Selector.matchElements(elements, expression || '*')[index || 0];
+  },
+
+  findChildElements: function(element, expressions) {
+    return expressions.map(function(expression) {
+      return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) {
+        var selector = new Selector(expr);
+        return results.inject([], function(elements, result) {
+          return elements.concat(selector.findElements(result || element));
+        });
+      });
+    }).flatten();
+  }
+});
+
+function $$() {
+  return Selector.findChildElements(document, $A(arguments));
+}
+var Form = {
+  reset: function(form) {
+    $(form).reset();
+    return form;
+  },
+
+  serializeElements: function(elements, getHash) {
+    var data = elements.inject({}, function(result, element) {
+      if (!element.disabled && element.name) {
+        var key = element.name, value = $(element).getValue();
+        if (value != undefined) {
+          if (result[key]) {
+            if (result[key].constructor != Array) result[key] = [result[key]];
+            result[key].push(value);
+          }
+          else result[key] = value;
+        }
+      }
+      return result;
+    });
+
+    return getHash ? data : Hash.toQueryString(data);
+  }
+};
+
+Form.Methods = {
+  serialize: function(form, getHash) {
+    return Form.serializeElements(Form.getElements(form), getHash);
+  },
+
+  getElements: function(form) {
+    return $A($(form).getElementsByTagName('*')).inject([],
+      function(elements, child) {
+        if (Form.Element.Serializers[child.tagName.toLowerCase()])
+          elements.push(Element.extend(child));
+        return elements;
+      }
+    );
+  },
+
+  getInputs: function(form, typeName, name) {
+    form = $(form);
+    var inputs = form.getElementsByTagName('input');
+
+    if (!typeName && !name) return $A(inputs).map(Element.extend);
+
+    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
+      var input = inputs[i];
+      if ((typeName && input.type != typeName) || (name && input.name != name))
+        continue;
+      matchingInputs.push(Element.extend(input));
+    }
+
+    return matchingInputs;
+  },
+
+  disable: function(form) {
+    form = $(form);
+    form.getElements().each(function(element) {
+      element.blur();
+      element.disabled = 'true';
+    });
+    return form;
+  },
+
+  enable: function(form) {
+    form = $(form);
+    form.getElements().each(function(element) {
+      element.disabled = '';
+    });
+    return form;
+  },
+
+  findFirstElement: function(form) {
+    return $(form).getElements().find(function(element) {
+      return element.type != 'hidden' && !element.disabled &&
+        ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+    });
+  },
+
+  focusFirstElement: function(form) {
+    form = $(form);
+    form.findFirstElement().activate();
+    return form;
+  }
+}
+
+Object.extend(Form, Form.Methods);
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element = {
+  focus: function(element) {
+    $(element).focus();
+    return element;
+  },
+
+  select: function(element) {
+    $(element).select();
+    return element;
+  }
+}
+
+Form.Element.Methods = {
+  serialize: function(element) {
+    element = $(element);
+    if (!element.disabled && element.name) {
+      var value = element.getValue();
+      if (value != undefined) {
+        var pair = {};
+        pair[element.name] = value;
+        return Hash.toQueryString(pair);
+      }
+    }
+    return '';
+  },
+
+  getValue: function(element) {
+    element = $(element);
+    var method = element.tagName.toLowerCase();
+    return Form.Element.Serializers[method](element);
+  },
+
+  clear: function(element) {
+    $(element).value = '';
+    return element;
+  },
+
+  present: function(element) {
+    return $(element).value != '';
+  },
+
+  activate: function(element) {
+    element = $(element);
+    element.focus();
+    if (element.select && ( element.tagName.toLowerCase() != 'input' ||
+      !['button', 'reset', 'submit'].include(element.type) ) )
+      element.select();
+    return element;
+  },
+
+  disable: function(element) {
+    element = $(element);
+    element.disabled = true;
+    return element;
+  },
+
+  enable: function(element) {
+    element = $(element);
+    element.blur();
+    element.disabled = false;
+    return element;
+  }
+}
+
+Object.extend(Form.Element, Form.Element.Methods);
+var Field = Form.Element;
+var $F = Form.Element.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element.Serializers = {
+  input: function(element) {
+    switch (element.type.toLowerCase()) {
+      case 'checkbox':
+      case 'radio':
+        return Form.Element.Serializers.inputSelector(element);
+      default:
+        return Form.Element.Serializers.textarea(element);
+    }
+  },
+
+  inputSelector: function(element) {
+    return element.checked ? element.value : null;
+  },
+
+  textarea: function(element) {
+    return element.value;
+  },
+
+  select: function(element) {
+    return this[element.type == 'select-one' ?
+      'selectOne' : 'selectMany'](element);
+  },
+
+  selectOne: function(element) {
+    var index = element.selectedIndex;
+    return index >= 0 ? this.optionValue(element.options[index]) : null;
+  },
+
+  selectMany: function(element) {
+    var values, length = element.length;
+    if (!length) return null;
+
+    for (var i = 0, values = []; i < length; i++) {
+      var opt = element.options[i];
+      if (opt.selected) values.push(this.optionValue(opt));
+    }
+    return values;
+  },
+
+  optionValue: function(opt) {
+    // extend element because hasAttribute may not be native
+    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
+  }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.TimedObserver = function() {}
+Abstract.TimedObserver.prototype = {
+  initialize: function(element, frequency, callback) {
+    this.frequency = frequency;
+    this.element   = $(element);
+    this.callback  = callback;
+
+    this.lastValue = this.getValue();
+    this.registerCallback();
+  },
+
+  registerCallback: function() {
+    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  onTimerEvent: function() {
+    var value = this.getValue();
+    var changed = ('string' == typeof this.lastValue && 'string' == typeof value
+      ? this.lastValue != value : String(this.lastValue) != String(value));
+    if (changed) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  }
+}
+
+Form.Element.Observer = Class.create();
+Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.Observer = Class.create();
+Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.EventObserver = function() {}
+Abstract.EventObserver.prototype = {
+  initialize: function(element, callback) {
+    this.element  = $(element);
+    this.callback = callback;
+
+    this.lastValue = this.getValue();
+    if (this.element.tagName.toLowerCase() == 'form')
+      this.registerFormCallbacks();
+    else
+      this.registerCallback(this.element);
+  },
+
+  onElementEvent: function() {
+    var value = this.getValue();
+    if (this.lastValue != value) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  },
+
+  registerFormCallbacks: function() {
+    Form.getElements(this.element).each(this.registerCallback.bind(this));
+  },
+
+  registerCallback: function(element) {
+    if (element.type) {
+      switch (element.type.toLowerCase()) {
+        case 'checkbox':
+        case 'radio':
+          Event.observe(element, 'click', this.onElementEvent.bind(this));
+          break;
+        default:
+          Event.observe(element, 'change', this.onElementEvent.bind(this));
+          break;
+      }
+    }
+  }
+}
+
+Form.Element.EventObserver = Class.create();
+Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.EventObserver = Class.create();
+Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+if (!window.Event) {
+  var Event = new Object();
+}
+
+Object.extend(Event, {
+  KEY_BACKSPACE: 8,
+  KEY_TAB:       9,
+  KEY_RETURN:   13,
+  KEY_ESC:      27,
+  KEY_LEFT:     37,
+  KEY_UP:       38,
+  KEY_RIGHT:    39,
+  KEY_DOWN:     40,
+  KEY_DELETE:   46,
+  KEY_HOME:     36,
+  KEY_END:      35,
+  KEY_PAGEUP:   33,
+  KEY_PAGEDOWN: 34,
+
+  element: function(event) {
+    return event.target || event.srcElement;
+  },
+
+  isLeftClick: function(event) {
+    return (((event.which) && (event.which == 1)) ||
+            ((event.button) && (event.button == 1)));
+  },
+
+  pointerX: function(event) {
+    return event.pageX || (event.clientX +
+      (document.documentElement.scrollLeft || document.body.scrollLeft));
+  },
+
+  pointerY: function(event) {
+    return event.pageY || (event.clientY +
+      (document.documentElement.scrollTop || document.body.scrollTop));
+  },
+
+  stop: function(event) {
+    if (event.preventDefault) {
+      event.preventDefault();
+      event.stopPropagation();
+    } else {
+      event.returnValue = false;
+      event.cancelBubble = true;
+    }
+  },
+
+  // find the first node with the given tagName, starting from the
+  // node the event was triggered on; traverses the DOM upwards
+  findElement: function(event, tagName) {
+    var element = Event.element(event);
+    while (element.parentNode && (!element.tagName ||
+        (element.tagName.toUpperCase() != tagName.toUpperCase())))
+      element = element.parentNode;
+    return element;
+  },
+
+  observers: false,
+
+  _observeAndCache: function(element, name, observer, useCapture) {
+    if (!this.observers) this.observers = [];
+    if (element.addEventListener) {
+      this.observers.push([element, name, observer, useCapture]);
+      element.addEventListener(name, observer, useCapture);
+    } else if (element.attachEvent) {
+      this.observers.push([element, name, observer, useCapture]);
+      element.attachEvent('on' + name, observer);
+    }
+  },
+
+  unloadCache: function() {
+    if (!Event.observers) return;
+    for (var i = 0, length = Event.observers.length; i < length; i++) {
+      Event.stopObserving.apply(this, Event.observers[i]);
+      Event.observers[i][0] = null;
+    }
+    Event.observers = false;
+  },
+
+  observe: function(element, name, observer, useCapture) {
+    element = $(element);
+    useCapture = useCapture || false;
+
+    if (name == 'keypress' &&
+        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+        || element.attachEvent))
+      name = 'keydown';
+
+    Event._observeAndCache(element, name, observer, useCapture);
+  },
+
+  stopObserving: function(element, name, observer, useCapture) {
+    element = $(element);
+    useCapture = useCapture || false;
+
+    if (name == 'keypress' &&
+        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+        || element.detachEvent))
+      name = 'keydown';
+
+    if (element.removeEventListener) {
+      element.removeEventListener(name, observer, useCapture);
+    } else if (element.detachEvent) {
+      try {
+        element.detachEvent('on' + name, observer);
+      } catch (e) {}
+    }
+  }
+});
+
+/* prevent memory leaks in IE */
+if (navigator.appVersion.match(/\bMSIE\b/))
+  Event.observe(window, 'unload', Event.unloadCache, false);
+var Position = {
+  // set to true if needed, warning: firefox performance problems
+  // NOT neeeded for page scrolling, only if draggable contained in
+  // scrollable elements
+  includeScrollOffsets: false,
+
+  // must be called before calling withinIncludingScrolloffset, every time the
+  // page is scrolled
+  prepare: function() {
+    this.deltaX =  window.pageXOffset
+                || document.documentElement.scrollLeft
+                || document.body.scrollLeft
+                || 0;
+    this.deltaY =  window.pageYOffset
+                || document.documentElement.scrollTop
+                || document.body.scrollTop
+                || 0;
+  },
+
+  realOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.scrollTop  || 0;
+      valueL += element.scrollLeft || 0;
+      element = element.parentNode;
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  cumulativeOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  positionedOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+      if (element) {
+        if(element.tagName=='BODY') break;
+        var p = Element.getStyle(element, 'position');
+        if (p == 'relative' || p == 'absolute') break;
+      }
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  offsetParent: function(element) {
+    if (element.offsetParent) return element.offsetParent;
+    if (element == document.body) return element;
+
+    while ((element = element.parentNode) && element != document.body)
+      if (Element.getStyle(element, 'position') != 'static')
+        return element;
+
+    return document.body;
+  },
+
+  // caches x/y coordinate pair to use with overlap
+  within: function(element, x, y) {
+    if (this.includeScrollOffsets)
+      return this.withinIncludingScrolloffsets(element, x, y);
+    this.xcomp = x;
+    this.ycomp = y;
+    this.offset = this.cumulativeOffset(element);
+
+    return (y >= this.offset[1] &&
+            y <  this.offset[1] + element.offsetHeight &&
+            x >= this.offset[0] &&
+            x <  this.offset[0] + element.offsetWidth);
+  },
+
+  withinIncludingScrolloffsets: function(element, x, y) {
+    var offsetcache = this.realOffset(element);
+
+    this.xcomp = x + offsetcache[0] - this.deltaX;
+    this.ycomp = y + offsetcache[1] - this.deltaY;
+    this.offset = this.cumulativeOffset(element);
+
+    return (this.ycomp >= this.offset[1] &&
+            this.ycomp <  this.offset[1] + element.offsetHeight &&
+            this.xcomp >= this.offset[0] &&
+            this.xcomp <  this.offset[0] + element.offsetWidth);
+  },
+
+  // within must be called directly before
+  overlap: function(mode, element) {
+    if (!mode) return 0;
+    if (mode == 'vertical')
+      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
+        element.offsetHeight;
+    if (mode == 'horizontal')
+      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
+        element.offsetWidth;
+  },
+
+  page: function(forElement) {
+    var valueT = 0, valueL = 0;
+
+    var element = forElement;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+
+      // Safari fix
+      if (element.offsetParent==document.body)
+        if (Element.getStyle(element,'position')=='absolute') break;
+
+    } while (element = element.offsetParent);
+
+    element = forElement;
+    do {
+      if (!window.opera || element.tagName=='BODY') {
+        valueT -= element.scrollTop  || 0;
+        valueL -= element.scrollLeft || 0;
+      }
+    } while (element = element.parentNode);
+
+    return [valueL, valueT];
+  },
+
+  clone: function(source, target) {
+    var options = Object.extend({
+      setLeft:    true,
+      setTop:     true,
+      setWidth:   true,
+      setHeight:  true,
+      offsetTop:  0,
+      offsetLeft: 0
+    }, arguments[2] || {})
+
+    // find page position of source
+    source = $(source);
+    var p = Position.page(source);
+
+    // find coordinate system to use
+    target = $(target);
+    var delta = [0, 0];
+    var parent = null;
+    // delta [0,0] will do fine with position: fixed elements,
+    // position:absolute needs offsetParent deltas
+    if (Element.getStyle(target,'position') == 'absolute') {
+      parent = Position.offsetParent(target);
+      delta = Position.page(parent);
+    }
+
+    // correct by body offsets (fixes Safari)
+    if (parent == document.body) {
+      delta[0] -= document.body.offsetLeft;
+      delta[1] -= document.body.offsetTop;
+    }
+
+    // set position
+    if(options.setLeft)   target.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
+    if(options.setTop)    target.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
+    if(options.setWidth)  target.style.width = source.offsetWidth + 'px';
+    if(options.setHeight) target.style.height = source.offsetHeight + 'px';
+  },
+
+  absolutize: function(element) {
+    element = $(element);
+    if (element.style.position == 'absolute') return;
+    Position.prepare();
+
+    var offsets = Position.positionedOffset(element);
+    var top     = offsets[1];
+    var left    = offsets[0];
+    var width   = element.clientWidth;
+    var height  = element.clientHeight;
+
+    element._originalLeft   = left - parseFloat(element.style.left  || 0);
+    element._originalTop    = top  - parseFloat(element.style.top || 0);
+    element._originalWidth  = element.style.width;
+    element._originalHeight = element.style.height;
+
+    element.style.position = 'absolute';
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.width  = width + 'px';
+    element.style.height = height + 'px';
+  },
+
+  relativize: function(element) {
+    element = $(element);
+    if (element.style.position == 'relative') return;
+    Position.prepare();
+
+    element.style.position = 'relative';
+    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
+    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.height = element._originalHeight;
+    element.style.width  = element._originalWidth;
+  }
+}
+
+// Safari returns margins on body which is incorrect if the child is absolutely
+// positioned.  For performance reasons, redefine Position.cumulativeOffset for
+// KHTML/WebKit only.
+if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
+  Position.cumulativeOffset = function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      if (element.offsetParent == document.body)
+        if (Element.getStyle(element, 'position') == 'absolute') break;
+
+      element = element.offsetParent;
+    } while (element);
+
+    return [valueL, valueT];
+  }
+}
+
+Element.addMethods();
\ No newline at end of file

Added: branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/weatherPortlet.html
===================================================================
--- branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/weatherPortlet.html	                        (rev 0)
+++ branches/UIServer/uiserver/src/resources/client/ajax/src/org/jboss/portal/presentation/ajax/public/weatherPortlet.html	2007-11-16 16:47:30 UTC (rev 8976)
@@ -0,0 +1,76 @@
+<div class="portlet-container"><table width="100%" border="0" cellpadding="0" cellspacing="0"><tr><td class="portlet-titlebar-left"></td><td class="portlet-titlebar-center"><div class="portlet-titlebar-decoration"></div><span class="portlet-titlebar-title">Weather Portlet</span><div class="portlet-mode-container"><span title="minimized"><a class="portlet-mode-minimized" href="/portal/portal/default/default/2?windowstate=minimized">&nbsp;</a></span><span title="maximized"><a class="portlet-mode-maximized" href="/portal/portal/default/default/2?windowstate=maximized">&nbsp;</a></span></div></td><td class="portlet-titlebar-right"></td></tr><tr><td class="portlet-content-left"></td><td class="portlet-body"><div class="portlet-content-center"><br/>
+<div align="center">
+<font>
+<b>Miami, FL, US</b>
+</font>
+
+<br/>
+<br/>
+<table border="0" width="130">
+<tr>
+<td>
+<table height="130" border="0">
+<tr>
+<td align="center" class="portlet-section-header">Currently</td>
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">
+<img src="http://us.i1.yimg.com/us.yimg.com/i/us/we/52//28.gif"/>
+</td>
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">Mostly Cloudy</td>
+
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">86F</td>
+</tr>
+</table>
+</td>
+<td>
+<table height="130" border="0">
+<tr>
+<td valign="top" align="center" class="portlet-section-header">Thu</td>
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">
+<img src="http://us.i1.yimg.com/us.yimg.com/i/us/we/52//38.gif"/>
+</td>
+
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">Scattered Thunderstorms</td>
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">76F/86F</td>
+</tr>
+</table>
+</td>
+<td>
+<table height="130" border="0">
+<tr>
+<td valign="top" align="center" class="portlet-section-header">Fri</td>
+</tr>
+
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">
+<img src="http://us.i1.yimg.com/us.yimg.com/i/us/we/52//38.gif"/>
+</td>
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">Scattered Thunderstorms</td>
+</tr>
+<tr>
+<td valign="top" align="center" class="portlet-section-alternate">78F/89F</td>
+</tr>
+</table>
+</td>
+</tr>
+</table>
+
+<br/>
+<a target="_blank" href="http://us.rd.yahoo.com/dailynews/rss/weather/Miami__FL/*http://weather.yahoo.com/forecast/33145_f.html">Complete Forecast</a>
+</div>
+</div></td><td class="portlet-content-right"></td></tr><tr><td class="portlet-footer-left"></td><td class="portlet-footer-center"></td><td class="portlet-footer-right"></td></tr></table>
+
+</div>
\ No newline at end of file

Modified: branches/UIServer/uiserver/src/resources/portal-uiserver.sar/META-INF/jboss-service.xml
===================================================================
--- branches/UIServer/uiserver/src/resources/portal-uiserver.sar/META-INF/jboss-service.xml	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/src/resources/portal-uiserver.sar/META-INF/jboss-service.xml	2007-11-16 16:47:30 UTC (rev 8976)
@@ -24,7 +24,7 @@
 
 <server>
   <mbean
-      code="org.jboss.portal.presentation.service.UIServer"
+      code="org.jboss.portal.presentation.controller.UIController"
       name="portal:service=Controller"
       xmbean-dd=""
       xmbean-code="org.jboss.portal.jems.as.system.JBossServiceModelMBean">
@@ -32,7 +32,7 @@
       <depends optional-attribute-name="PresentationServer" proxy-type="attribute">portal:service=PresentationServer</depends>      
   </mbean>
   <mbean
-      code="org.jboss.portal.presentation.service.EntryPointImpl"
+      code="org.jboss.portal.presentation.impl.entry.EntryPointImpl"
       name="portal:service=EntryPoint"
       xmbean-dd=""
       xmbean-code="org.jboss.portal.jems.as.system.JBossServiceModelMBean">

Modified: branches/UIServer/uiserver/src/resources/portal-uiserver.war/WEB-INF/web.xml
===================================================================
--- branches/UIServer/uiserver/src/resources/portal-uiserver.war/WEB-INF/web.xml	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/src/resources/portal-uiserver.war/WEB-INF/web.xml	2007-11-16 16:47:30 UTC (rev 8976)
@@ -27,20 +27,21 @@
    "http://java.sun.com/dtd/web-app_2_3.dtd">
 <web-app> 
    <!-- Add the GWT Client Filter to run the Portal in full Web 2.0 Ajax Mode. In turn, to run in Classic Html Mode, turn this filter off -->
+   <!--
    <filter>
    		<filter-name>GWTClientFilter</filter-name>
-   		<filter-class>org.jboss.portal.presentation.service.GWTClientFilter</filter-class>
+   		<filter-class>org.jboss.portal.presentation.entry.GWTClientFilter</filter-class>
    </filter>    
    <filter-mapping>
    		<filter-name>GWTClientFilter</filter-name>
    		<servlet-name>PortalEntryPoint</servlet-name>
    </filter-mapping>
+   -->
 
-
    <!-- The portal servlet is the main entrance point -->
    <servlet>
       <servlet-name>PortalEntryPoint</servlet-name>
-      <servlet-class>org.jboss.portal.presentation.service.PortalEntryPoint</servlet-class>
+      <servlet-class>org.jboss.portal.presentation.impl.classic.entry.PortalEntryPoint</servlet-class>
       <init-param>
          <param-name>asDefaultServlet</param-name>
          <param-value>false</param-value>
@@ -74,7 +75,7 @@
    <!-- Asynchronous service request processor -->
    <servlet>
       <servlet-name>AjaxPortalEntryPoint</servlet-name>
-      <servlet-class>org.jboss.portal.presentation.impl.ajax.service.PortalEntryPoint</servlet-class>
+      <servlet-class>org.jboss.portal.presentation.impl.ajax.entry.PortalEntryPoint</servlet-class>
       <init-param>
          <param-name>asDefaultServlet</param-name>
          <param-value>false</param-value>

Modified: branches/UIServer/uiserver/src/resources/portal-uiserver.war/asyncPages.html
===================================================================
--- branches/UIServer/uiserver/src/resources/portal-uiserver.war/asyncPages.html	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/src/resources/portal-uiserver.war/asyncPages.html	2007-11-16 16:47:30 UTC (rev 8976)
@@ -1,6 +1,6 @@
 <html>
 	<head>
-		<meta http-equiv="refresh" content="0;url=org.jboss.portal.uiserver.ajax.AsyncPages/asyncPages.html">
+		<meta http-equiv="refresh" content="0;url=org.jboss.portal.presentation.ajax.AsyncPages/asyncPages.html">
 	</head>
 	<body>
 	</body>

Modified: branches/UIServer/uiserver/src/resources/portal-uiserver.war/layout.html
===================================================================
--- branches/UIServer/uiserver/src/resources/portal-uiserver.war/layout.html	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/src/resources/portal-uiserver.war/layout.html	2007-11-16 16:47:30 UTC (rev 8976)
@@ -1,6 +1,6 @@
 <html>
 	<head>
-		<meta http-equiv="refresh" content="0;url=org.jboss.portal.uiserver.ajax.PortalLayout/layout.html">
+		<meta http-equiv="refresh" content="0;url=org.jboss.portal.presentation.ajax.PortalLayout/layout.html">
 	</head>
 	<body>
 	</body>

Modified: branches/UIServer/uiserver/src/resources/portal-uiserver.war/partialRefresh.html
===================================================================
--- branches/UIServer/uiserver/src/resources/portal-uiserver.war/partialRefresh.html	2007-11-16 15:13:46 UTC (rev 8975)
+++ branches/UIServer/uiserver/src/resources/portal-uiserver.war/partialRefresh.html	2007-11-16 16:47:30 UTC (rev 8976)
@@ -1,6 +1,6 @@
 <html>
 	<head>
-		<meta http-equiv="refresh" content="0;url=org.jboss.portal.uiserver.ajax.PartialRefresh/partialRefresh.html">
+		<meta http-equiv="refresh" content="0;url=org.jboss.portal.presentation.ajax.PartialRefresh/partialRefresh.html">
 	</head>
 	<body>
 	</body>




More information about the portal-commits mailing list