GateIn Standalone Application

Version 6

    Description

    The goal of this specification is to add the capability for GateIn to display a single application with no decoration around it in a browser window. So it is almost like a portal that would only show a single window without a concept of page. The first version of this specification will focus on displaying gadgets as standalone applications, but later we will provide a new version of this specification that will work for both gadgets and portlets.

    Solution

    Today we have a PortalRequestHandler that process a request and triggers the lifecycle of a UIPortalApplication. The UIPortalApplication class extends the UIApplication class, the component hierarchy contained by a UIPortalApplication is quite complex and it contains pages, each page contains a page structure finally containing UIPortlet.

    We want to create a new UIApplication extension called UIStandaloneApplication that extends UIApplication and that has only one single component that is a viewport onto a portal page window. A window in GateIn has an unique identifier. When displaying a gadget, the gadget markup would have an attribute that would provide the associated standalone application URL. This application URL would provide interactions with the same window in the server which are render and process action defined in webui component framework.

    The UIStandaloneApplication will be exposed as a StandaloneRequestHandler that will process an URL bound on /application (subject to change).

    Specification

    Configuration Change

    Users must login before use StandaloneApplication for now. So, add it to security constraints

        <security-constraint>
            <web-resource-collection>
              <web-resource-name>user authentication</web-resource-name>
              <url-pattern>/private/*</url-pattern>
              <url-pattern>/standalone/*</url-pattern>
              <http-method>POST</http-method>
              <http-method>GET</http-method>
          </web-resource-collection>
           .........................
        </security-constraint>

    WebRequestHandler in gatein like : PortalRequestHandler or StandaloneRequestHandler should be used as plugin, so we can add new handler by add new config (don't need to modify the PortalController any more), webui-configuration file can be set by using <init-params> element too

    <external-component-plugins>
          <target-component>org.exoplatform.web.WebAppController</target-component>
          <component-plugin>
             <name>StandaloneAppRequestHandler</name>
             <set-method>register</set-method>
             <type>org.exoplatform.portal.application.StandaloneAppRequestHandler</type>
             <init-params>
                <value-param>
                   <name>webui.configuration</name>
                   <value>app:/WEB-INF/standalone-webui-configuration.xml</value>
                </value-param>
             </init-params>
          </component-plugin>
       </external-component-plugins>

    DataStorage

    The DataStorage interface and its implementation requires a modification to be able to operate on objects of type org.exoplatform.portal.config.model.Application . Indeed until now it only cared about the notion of page and now we need a finer grained access to components of a page.

    For the first step, we need methods retrieving Application model, site type and site owner

    public <S> Application<S> getApplicationModel(String applicationStorageId) throws Exception;

     

    public String[] getSiteInfo(String applicationStorageId) throws Exception;

    Implementation of two newly declared methods in DataStorageImpl

    public <S> Application<S> getApplicationModel(String applicationStorageId) throws Exception

    {

        try{

          ApplicationData<S> data = delegate.getApplicationData(applicationStorageId);

          return new Application<S>(data);

        }catch(NoSuchDataException ex)

        {

          throw ex;

        }

    }

     

    public String[] getSiteInfo(String applicationStorageId) throws Exception {

         return delegate.getSiteInfo(applicationStorageId);

    }

    Relevant changes in ModelDataStorage

    public <S> ApplicationData getApplicationModel(String applicationStorageId) throws Exception;

     

    public String[] getSiteInfo(String applicationStorageId) throws Exception;

    Implementation of two newly declared methods in POMDataStorage

    public <S> ApplicationData<S> getApplicationData(String applicationStorageId)throws Exception
    {

           POMSession session = pomMgr.getSession();

           WorkspaceObject workspaceObject = session.findObjectById(applicationStorageId);

     

           if(workspaceObject instanceof UIWindow)

           {

               UIWindow application = (UIWindow)workspaceObject;

               return new Mapper(session).load(application);

           }

     

           throw new NoSuchDataException("Could not load the application data specified by the ID: " + applicationStorageId);

    }

     

    public String[] getSiteInfo(String applicationStorageId) throws Exception

    {

           POMSession session = pomMgr.getSession();

     

           WorkspaceObject workspaceObject = session.findObjectById(workspaceObjectId);

     

           if(workspaceObject instanceof UIComponent)

           {

               Site site = ((UIComponent)workspaceObject).getPage().getSite();

               ObjectType<? extends Site> siteType = site.getObjectType();

     

               Map<String, String> returnedMap = new HashMap<String, String>();

     

               //Put the siteType on returned map

               if(siteType == ObjectType.PORTAL_SITE)

               {

                   returnedMap.put("siteType", "portal");

               }

               else if(siteType == ObjectType.GROUP_SITE)

               {

                   returnedMap.put("siteType", "group");

               }else if(siteType == ObjectType.USER_SITE)

               {

                   returnedMap.put("siteType", "user");

               }

     

               //Put the siteOwner on returned map

               returnedMap.put("siteOwner", site.getName());

     

               return returnedMap;

           }

     

           throw new Exception("The provided ID is not associated with an application");

    }