rave-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From carlu...@apache.org
Subject svn commit: r1199600 - in /incubator/rave/trunk: ./ rave-components/rave-web/ rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/ rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/util/ rave-componen...
Date Wed, 09 Nov 2011 02:28:40 GMT
Author: carlucci
Date: Wed Nov  9 02:28:39 2011
New Revision: 1199600

URL: http://svn.apache.org/viewvc?rev=1199600&view=rev
Log:
RAVE-342: Add Spring Mobile server side support to detect mobile clients and return mobile
views

Added:
    incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/util/
  (with props)
    incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/util/ControllerUtils.java
    incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/
  (with props)
    incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/ControllerUtilsTest.java
    incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/MockHttpUtil.java
    incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/mobile_home.jsp
Modified:
    incubator/rave/trunk/pom.xml
    incubator/rave/trunk/rave-components/rave-web/pom.xml
    incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/PageController.java
    incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/ViewNames.java
    incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/PageControllerTest.java
    incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/dispatcher-servlet.xml
    incubator/rave/trunk/rave-portal-resources/src/main/webapp/css/default.css
    incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave.js
    incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave_api.js

Modified: incubator/rave/trunk/pom.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/pom.xml?rev=1199600&r1=1199599&r2=1199600&view=diff
==============================================================================
--- incubator/rave/trunk/pom.xml (original)
+++ incubator/rave/trunk/pom.xml Wed Nov  9 02:28:39 2011
@@ -46,6 +46,7 @@
     <properties>
         <apache.shindig.version>3.0.0-beta2</apache.shindig.version>
         <org.springframework.version>3.0.5.RELEASE</org.springframework.version>
+        <org.springframework.mobile.version>1.0.0.M3</org.springframework.mobile.version>
       
         <jstl.version>1.2</jstl.version>
         <javax.servlet.version>2.5</javax.servlet.version>
         <jsp-api.version>2.1</jsp-api.version>
@@ -91,6 +92,11 @@
                 <enabled>false</enabled>
             </releases>
         </repository>
+        <repository>
+            <id>spring-milestone</id>
+            <name>Spring Maven MILESTONE Repository</name>
+            <url>http://maven.springframework.org/milestone</url>
+        </repository>
     </repositories>
 
     <!-- Global management of all dependencies -->
@@ -216,6 +222,11 @@
                 <version>${org.springframework.version}</version>
             </dependency>
             <dependency>
+                 <groupId>org.springframework.mobile</groupId>
+                 <artifactId>spring-mobile-device</artifactId>
+                 <version>${org.springframework.mobile.version}</version>
+            </dependency>                        
+            <dependency>
                 <groupId>com.google.inject.extensions</groupId>
                 <artifactId>guice-persist</artifactId>
                 <version>${guice.version}</version>

Modified: incubator/rave/trunk/rave-components/rave-web/pom.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/pom.xml?rev=1199600&r1=1199599&r2=1199600&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/pom.xml (original)
+++ incubator/rave/trunk/rave-components/rave-web/pom.xml Wed Nov  9 02:28:39 2011
@@ -56,7 +56,10 @@
             <groupId>org.springframework.security</groupId>
             <artifactId>spring-security-web</artifactId>
         </dependency>
-
+        <dependency>
+            <groupId>org.springframework.mobile</groupId>
+            <artifactId>spring-mobile-device</artifactId>
+        </dependency>
         <!-- Validation -->
         <dependency>
             <groupId>commons-validator</groupId>

Modified: incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/PageController.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/PageController.java?rev=1199600&r1=1199599&r2=1199600&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/PageController.java
(original)
+++ incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/PageController.java
Wed Nov  9 02:28:39 2011
@@ -18,7 +18,6 @@
  */
 package org.apache.rave.portal.web.controller;
 
-import java.util.ArrayList;
 import org.apache.rave.portal.model.Page;
 import org.apache.rave.portal.model.User;
 import org.apache.rave.portal.service.PageService;
@@ -35,6 +34,8 @@ import org.springframework.web.bind.anno
 import org.springframework.web.bind.annotation.RequestMethod;
 
 import java.util.List;
+import javax.servlet.http.HttpServletRequest;
+import org.apache.rave.portal.web.controller.util.ControllerUtils;
 
 /**
  * Page Controller
@@ -55,15 +56,15 @@ public class PageController {
     }
  
     @RequestMapping(value = {"/page/view", "/index.html"}, method = RequestMethod.GET)
-    public String viewDefault(Model model) {
+    public String viewDefault(Model model, HttpServletRequest request) {
         List<Page> pages = getAllPagesForAuthenticatedUser();
         model.addAttribute(ModelKeys.PAGE, pageService.getDefaultPageFromList(pages));
         model.addAttribute(ModelKeys.PAGES, pages);
-        return ViewNames.HOME;
+        return getDeviceAppropriateView(request);
     }          
     
     @RequestMapping(value = "/page/view/{pageId}", method = RequestMethod.GET)
-    public String view(@PathVariable Long pageId, Model model) {
+    public String view(@PathVariable Long pageId, Model model, HttpServletRequest request)
{
         User user = userService.getAuthenticatedUser();
         logger.debug("attempting to get pageId " + pageId + " for " + user);
         
@@ -72,7 +73,7 @@ public class PageController {
                
         model.addAttribute(ModelKeys.PAGE, page);
         model.addAttribute(ModelKeys.PAGES, pages);
-        return ViewNames.HOME;
+        return getDeviceAppropriateView(request);
     }
     
     private List<Page> getAllPagesForAuthenticatedUser() {
@@ -87,5 +88,18 @@ public class PageController {
             pages = pageService.getAllPages(userId);
         }
         return pages;
-    }    
-}
+    }
+    
+    private String getDeviceAppropriateView(HttpServletRequest request) {
+        // return the appropriate View name based on the request.  It
+        // checks to see if the user is on a mobile device or not
+        String viewName = null;
+        if (ControllerUtils.isMobileDevice(request)) {            
+            viewName = ViewNames.MOBILE_HOME;
+        } else {           
+            viewName = ViewNames.HOME;
+        }            
+        
+        return viewName;
+    }
+}
\ No newline at end of file

Propchange: incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/util/
------------------------------------------------------------------------------
    bugtraq:number = true

Added: incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/util/ControllerUtils.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/util/ControllerUtils.java?rev=1199600&view=auto
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/util/ControllerUtils.java
(added)
+++ incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/util/ControllerUtils.java
Wed Nov  9 02:28:39 2011
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.rave.portal.web.controller.util;
+
+import javax.servlet.http.HttpServletRequest;
+import org.springframework.mobile.device.DeviceUtils;
+
+public class ControllerUtils {
+    /**
+     * Utility function to determine if this HttpServletRequest 
+     * is coming from a mobile client 
+     * 
+     * @param request the HttpServletRequest from the client
+     * @return true if the client is a mobile device, false if not mobile
+     */
+    public static boolean isMobileDevice(HttpServletRequest request) {
+        return DeviceUtils.getCurrentDevice(request).isMobile();
+    }    
+}
\ No newline at end of file

Modified: incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/ViewNames.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/ViewNames.java?rev=1199600&r1=1199599&r2=1199600&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/ViewNames.java
(original)
+++ incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/ViewNames.java
Wed Nov  9 02:28:39 2011
@@ -27,6 +27,7 @@ public class ViewNames {
     private static final String USER_PREFIX = "templates.user.";
 
     public static final String HOME = USER_PREFIX + "home";
+    public static final String MOBILE_HOME = USER_PREFIX + "mobile_home";    
     public static final String STORE = "store";
     public static final String WIDGET = "widget";
     public static final String ADD_WIDGET_FORM = "addwidget";

Modified: incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/PageControllerTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/PageControllerTest.java?rev=1199600&r1=1199599&r2=1199600&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/PageControllerTest.java
(original)
+++ incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/PageControllerTest.java
Wed Nov  9 02:28:39 2011
@@ -19,6 +19,8 @@
 
 package org.apache.rave.portal.web.controller;
 
+import org.apache.rave.portal.web.controller.util.MockHttpUtil;
+import org.springframework.mock.web.MockHttpServletRequest;
 import org.apache.rave.portal.model.PageLayout;
 import org.apache.rave.portal.model.Page;
 import org.apache.rave.portal.model.User;
@@ -34,6 +36,7 @@ import org.springframework.ui.Model;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.rave.portal.web.util.ViewNames;
 import static org.hamcrest.CoreMatchers.*;
 import static org.easymock.EasyMock.*;
 import static org.junit.Assert.assertThat;
@@ -42,6 +45,7 @@ public class PageControllerTest {
     private UserService userService;
     private PageService pageService;
     private PageController pageController;
+    private MockHttpServletRequest request;
     
     private Model model;
     private Page defaultPage, otherPage;
@@ -60,7 +64,8 @@ public class PageControllerTest {
         pageService = createMock(PageService.class);
         pageController = new PageController(pageService, userService);
         model = new ExtendedModelMap();
-        
+        request = new MockHttpServletRequest();
+                
         defaultPage = new Page(DEFAULT_PAGE_ID);
         otherPage = new Page(OTHER_PAGE_ID);
         
@@ -78,12 +83,14 @@ public class PageControllerTest {
 
     @Test
     public void view_pageId() {
+        MockHttpUtil.setupRequestAsNonMobileUserAgent(request);        
+        
         expect(userService.getAuthenticatedUser()).andReturn(validUser).anyTimes(); 
         expect(pageService.getAllPages(USER_ID)).andReturn(allPages);
         expect(pageService.getPageFromList(OTHER_PAGE_ID, allPages)).andReturn(otherPage);
         replay(userService, pageService);       
 
-        String results = pageController.view(OTHER_PAGE_ID, model);
+        String results = pageController.view(OTHER_PAGE_ID, model, request);
         
         assertThat(results, equalTo(ViewNames.HOME));
         assertThat((Page) model.asMap().get(ModelKeys.PAGE), sameInstance(otherPage));
@@ -93,7 +100,26 @@ public class PageControllerTest {
     }
     
     @Test
+    public void view_pageId_mobileClient() {       
+        MockHttpUtil.setupRequestAsMobileUserAgent(request);
+        
+        expect(userService.getAuthenticatedUser()).andReturn(validUser).anyTimes(); 
+        expect(pageService.getAllPages(USER_ID)).andReturn(allPages);
+        expect(pageService.getPageFromList(OTHER_PAGE_ID, allPages)).andReturn(otherPage);
+        replay(userService, pageService);       
+
+        String results = pageController.view(OTHER_PAGE_ID, model, request);
+        
+        assertThat(results, equalTo(ViewNames.MOBILE_HOME));
+        assertThat((Page) model.asMap().get(ModelKeys.PAGE), sameInstance(otherPage));
+        assertThat((List<Page>) model.asMap().get(ModelKeys.PAGES), sameInstance(allPages));
+        
+        verify(userService, pageService);
+    }
+    
+    @Test
     public void view_pageId_zeroExistingPages() {
+        MockHttpUtil.setupRequestAsNonMobileUserAgent(request);        
         List<Page> pages = new ArrayList<Page>();
         
         assertThat(pages.isEmpty(), is(true));
@@ -103,7 +129,7 @@ public class PageControllerTest {
         expect(pageService.getPageFromList(OTHER_PAGE_ID, pages)).andReturn(defaultPage);
         replay(userService, pageService);         
         
-        String results = pageController.view(OTHER_PAGE_ID, model);
+        String results = pageController.view(OTHER_PAGE_ID, model, request);
         
         assertThat(results, equalTo(ViewNames.HOME));
         assertThat((Page) model.asMap().get(ModelKeys.PAGE), sameInstance(defaultPage));
@@ -114,12 +140,14 @@ public class PageControllerTest {
     
     @Test
     public void viewDefault_pageId() {
+        MockHttpUtil.setupRequestAsNonMobileUserAgent(request);        
+        
         expect(userService.getAuthenticatedUser()).andReturn(validUser).anyTimes(); 
         expect(pageService.getAllPages(USER_ID)).andReturn(allPages);
         expect(pageService.getDefaultPageFromList(allPages)).andReturn(defaultPage);
         replay(userService, pageService);
 
-        String results = pageController.viewDefault(model);
+        String results = pageController.viewDefault(model, request);
         
         assertThat(results, equalTo(ViewNames.HOME));
         assertThat((Page) model.asMap().get(ModelKeys.PAGE), sameInstance(defaultPage));
@@ -130,6 +158,7 @@ public class PageControllerTest {
     
     @Test
     public void viewDefault_pageId_zeroExistingPages() {
+        MockHttpUtil.setupRequestAsNonMobileUserAgent(request);        
         List<Page> pages = new ArrayList<Page>();
         
         assertThat(pages.isEmpty(), is(true));
@@ -139,7 +168,7 @@ public class PageControllerTest {
         expect(pageService.getDefaultPageFromList(pages)).andReturn(defaultPage);
         replay(userService, pageService);
 
-        String results = pageController.viewDefault(model);
+        String results = pageController.viewDefault(model, request);
         
         assertThat(results, equalTo(ViewNames.HOME));
         assertThat((Page) model.asMap().get(ModelKeys.PAGE), sameInstance(defaultPage));

Propchange: incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/
------------------------------------------------------------------------------
    bugtraq:number = true

Added: incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/ControllerUtilsTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/ControllerUtilsTest.java?rev=1199600&view=auto
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/ControllerUtilsTest.java
(added)
+++ incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/ControllerUtilsTest.java
Wed Nov  9 02:28:39 2011
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rave.portal.web.controller.util;
+
+import org.springframework.mock.web.MockHttpServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.CoreMatchers.*;
+
+public class ControllerUtilsTest {
+    private MockHttpServletRequest request;    
+    
+    @Before
+    public void setUp() {
+        request = new MockHttpServletRequest();
+    }
+    
+    @Test
+    public void testIsMobileDevice_mobileClient() {
+        MockHttpUtil.setupRequestAsMobileUserAgent(request);        
+        assertThat(ControllerUtils.isMobileDevice(request), is(true));       
+    }
+    
+    @Test
+    public void testIsMobileDevice_nonMobileClient() {
+        MockHttpUtil.setupRequestAsNonMobileUserAgent(request);        
+        assertThat(ControllerUtils.isMobileDevice(request), is(false));       
+    }
+}
\ No newline at end of file

Added: incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/MockHttpUtil.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/MockHttpUtil.java?rev=1199600&view=auto
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/MockHttpUtil.java
(added)
+++ incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/MockHttpUtil.java
Wed Nov  9 02:28:39 2011
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rave.portal.web.controller.util;
+
+import org.springframework.mobile.device.DeviceUtils;
+import org.springframework.mobile.device.LiteDeviceResolver;
+import org.springframework.mock.web.MockHttpServletRequest;
+
+public final class MockHttpUtil {
+    public static void setupRequestAsNonMobileUserAgent(MockHttpServletRequest mockHttpServletRequest)
{
+        mockHttpServletRequest.addHeader("User-Agent", "MSIE");         
+        mockHttpServletRequest.setAttribute(DeviceUtils.CURRENT_DEVICE_ATTRIBUTE, new LiteDeviceResolver().resolveDevice(mockHttpServletRequest));
+    }
+    
+    public static void setupRequestAsMobileUserAgent(MockHttpServletRequest mockHttpServletRequest)
{        
+        mockHttpServletRequest.addHeader("User-Agent", "Blackberry");         
+        mockHttpServletRequest.setAttribute(DeviceUtils.CURRENT_DEVICE_ATTRIBUTE, new LiteDeviceResolver().resolveDevice(mockHttpServletRequest));
+    }    
+}
+

Modified: incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/dispatcher-servlet.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/dispatcher-servlet.xml?rev=1199600&r1=1199599&r2=1199600&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/dispatcher-servlet.xml
(original)
+++ incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/dispatcher-servlet.xml
Wed Nov  9 02:28:39 2011
@@ -58,7 +58,16 @@
             </list>
         </property>
     </bean>
-
+    <mvc:interceptors>
+        <!-- On pre-handle, resolve the device that originated the web 
+             request and put that information into the ServletRequest object.
+             By default it will use the LiteDeviceResolver which only 
+             gives you very basic information, basically is this a 
+             mobile device or not.  A more advanced WurflDeviceResolver 
+             can be used if you need to get more detailed information about
+             the device such as manufacturer, model, screen size, etc.-->
+        <bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor"
/>
+    </mvc:interceptors>
     <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
         <property name="definitions">
             <list>

Added: incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/mobile_home.jsp
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/mobile_home.jsp?rev=1199600&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/mobile_home.jsp
(added)
+++ incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/mobile_home.jsp
Wed Nov  9 02:28:39 2011
@@ -0,0 +1,172 @@
+<%--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+  --%>
+<%@ page language="java" trimDirectiveWhitespaces="true" %>
+<%@ include file="/WEB-INF/jsp/includes/taglibs.jsp" %>
+<jsp:useBean id="pages" type="java.util.List<org.apache.rave.portal.model.Page>"
scope="request"/>
+<fmt:setBundle basename="messages"/>
+<%--@elvariable id="page" type="org.apache.rave.portal.model.Page"--%>
+<rave:rave_generic_page pageTitle="${page.name}">
+    <header class="header-mobile">
+        <nav class="topnav">
+            <ul class="horizontal-list">
+                <li>
+                    <a href="<spring:url value="/app/store?referringPageId=${page.entityId}"
/>">
+                      <fmt:message key="page.store.title"/>
+                    </a>
+                </li>
+                <li>
+                    <a href="<spring:url value="/j_spring_security_logout" htmlEscape="true"
/>">
+                      <fmt:message key="page.general.logout"/></a>
+                </li>
+            </ul>
+        </nav>
+      <h1>
+          <fmt:message key="page.home.welcome"><fmt:param><c:out value="${page.owner.username}"/></fmt:param></fmt:message>
+      </h1>
+    </header>
+    <input id="currentPageId" type="hidden" value="${page.entityId}" />
+    <c:set var="hasOnlyOnePage">
+        <c:choose>
+            <c:when test="${fn:length(pages) == 1}">true</c:when>
+            <c:otherwise>false</c:otherwise>
+        </c:choose>
+    </c:set>
+    <div id="tabsHeader">
+        <%-- render the page links --%>
+        <div id="tabs" class="rave-ui-tabs">
+            <c:forEach var="userPage" items="${pages}">
+                 <%-- determine if the current page in the list matches the page the user
is viewing --%>
+                 <c:set var="isCurrentPage">
+                     <c:choose>
+                         <c:when test="${page.entityId == userPage.entityId}">true</c:when>
+                         <c:otherwise>false</c:otherwise>
+                     </c:choose>
+                 </c:set>
+                 <div id="tab-${userPage.entityId}" class="rave-ui-tab rave-ui-tab-mobile<c:if
test="${isCurrentPage}"> rave-ui-tab-selected rave-ui-tab-selected-mobile</c:if>">
+                    <div id="pageTitle-${userPage.entityId}" class="page-title" onclick="rave.viewPage(${userPage.entityId});"><c:out
value="${userPage.name}"/></div>                   
+                </div>
+            </c:forEach>
+            <%-- display the add page button at the end of the tabs --%>
+            <fmt:message key="page.general.addnewpage" var="addNewPageTitle"/>
+            <button id="add_page" title="${addNewPageTitle}" style="display: none;"></button>
+        </div>
+    </div>
+    <%-- the mobile view will only show one column of widgets --%>
+    <div id="pageContent" class="pageContent-mobile">        
+        <c:forEach var="region" items="${page.regions}">
+            <div class="region region-mobile" id="region-${region.entityId}-id">
+            <c:forEach var="regionWidget" items="${region.regionWidgets}">
+               <div class="widget-wrapper widget-wrapper-mobile" id="widget-${regionWidget.entityId}-wrapper">
+                    <div class="widget-title-bar widget-title-bar-mobile" onclick="rave.toggleMobileWidget(${regionWidget.entityId});">
+                        <span id="widget-${regionWidget.entityId}-collapse" class="widget-toolbar-toggle-collapse"
title="<fmt:message key="widget.chrome.toggle"/>"></span>
+                        <div id="widget-${regionWidget.entityId}-title" class="widget-title">
+                            <c:out value="${regionWidget.widget.title}"/>         
              
+                        </div>                        
+                    </div>
+                    <div class="widget-prefs" id="widget-${regionWidget.entityId}-prefs-content"></div>
+                    <div class="widget widget-mobile" id="widget-${regionWidget.entityId}-body">
+                            <portal:render-widget regionWidget="${regionWidget}" />
+                    </div>
+                </div>
+            </c:forEach>
+            </div>
+        </c:forEach>
+    </div>
+    <fmt:message key="page.general.addnewpage" var="addNewPageTitle"/>
+    <div id="dialog" title="${addNewPageTitle}" class="dialog">
+        <form id="pageForm">
+            <div id="pageFormErrors" class="error"></div>
+            <fieldset class="ui-helper-reset">
+                <input type="hidden" name="tab_id" id="tab_id" value="" />
+                <label for="tab_title"><fmt:message key="page.general.addpage.title"/></label>
+                <input type="text" name="tab_title" id="tab_title" value="" class="required
ui-widget-content ui-corner-all" />
+                <label for="pageLayout"><fmt:message key="page.general.addpage.selectlayout"/></label>
+                <select name="pageLayout" id="pageLayout">
+                    <option value="columns_1" id="columns_1_id"><fmt:message key="page.general.addpage.layout.columns_1"/></option>
+                    <option value="columns_2" id="columns_2_id" selected="selected"><fmt:message
key="page.general.addpage.layout.columns_2"/></option>
+                    <option value="columns_2wn" id="columns_2wn_id"><fmt:message
key="page.general.addpage.layout.columns_2wn"/></option>
+                    <option value="columns_3" id="columns_3_id"><fmt:message key="page.general.addpage.layout.columns_3"/></option>
+                    <option value="columns_3nwn" id="columns_3nwn_id"><fmt:message
key="page.general.addpage.layout.columns_3nwn"/></option>
+                    <option value="columns_4" id="columns_4_id"><fmt:message key="page.general.addpage.layout.columns_4"/></option>
+                    <option value="columns_3nwn_1_bottom" id="columns_3nwn_1_bottom"><fmt:message
key="page.general.addpage.layout.columns_3nwn_1_bottom"/></option>
+                </select>
+            </fieldset>
+        </form>
+    </div>
+    <fmt:message key="page.general.movepage" var="movePageTitle"/>
+    <div id="movePageDialog" title="${movePageTitle}" class="dialog">
+        <div><fmt:message key="page.general.movethispage"/></div>
+        <form id="movePageForm">
+            <select id="moveAfterPageId">
+                <c:if test="${page.renderSequence != 1}">
+                    <option value="-1"><fmt:message key="page.general.movethispage.tofirst"/></option>
+                </c:if>
+                <c:forEach var="userPage" items="${pages}">
+                    <c:if test="${userPage.entityId != page.entityId}">
+                        <option value="${userPage.entityId}">
+                          <fmt:message key="page.general.movethispage.after">
+                              <fmt:param><c:out value="${userPage.name}"/></fmt:param>
+                          </fmt:message>
+                        </option>
+                    </c:if>
+                </c:forEach>
+            </select>
+        </form>
+    </div>
+    <fmt:message key="widget.menu.movetopage" var="moveWidgetToPageTitle"/>
+    <div id="moveWidgetDialog" title="${moveWidgetToPageTitle}" class="dialog">
+        <div><fmt:message key="widget.menu.movethiswidget"/></div>
+        <form id="moveWidgetForm">
+            <select id="moveToPageId">
+                <c:forEach var="userPage" items="${pages}">
+                    <c:if test="${userPage.entityId != page.entityId}">
+                        <option value="${userPage.entityId}">
+                            <c:out value="${userPage.name}"/>
+                        </option>
+                    </c:if>
+                </c:forEach>
+            </select>
+        </form>
+    </div>        
+    <script>
+        //Define the global widgets map.  This map will be populated by RegionWidgetRender
providers.
+        var widgetsByRegionIdMap = {};
+    </script>
+    <portal:render-script location="${'BEFORE_LIB'}" />
+    <script src="//cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js"></script>
+    <script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.1.min.js"></script>
+    <script src="//ajax.aspnetcdn.com/ajax/jquery.ui/1.8.13/jquery-ui.min.js"></script>
+    <script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.8.1/jquery.validate.min.js"></script>
+    <portal:render-script location="${'AFTER_LIB'}" />
+    <portal:render-script location="${'BEFORE_RAVE'}" />
+    <script src="<spring:url value="/script/rave.js"/>"></script>
+    <script src="<spring:url value="/script/rave_api.js"/>"></script>
+    <script src="<spring:url value="/script/rave_opensocial.js"/>"></script>
+    <script src="<spring:url value="/script/rave_wookie.js"/>"></script>
+    <script src="<spring:url value="/script/rave_layout.js"/>"></script>
+    <portal:render-script location="${'AFTER_RAVE'}" />
+    <script>
+        $(function() {
+            rave.setMobile(true);
+            rave.setContext("<spring:url value="/app/" />");
+            rave.initProviders();
+            rave.initWidgets(widgetsByRegionIdMap);           
+        });
+    </script>
+</rave:rave_generic_page>

Modified: incubator/rave/trunk/rave-portal-resources/src/main/webapp/css/default.css
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/main/webapp/css/default.css?rev=1199600&r1=1199599&r2=1199600&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal-resources/src/main/webapp/css/default.css (original)
+++ incubator/rave/trunk/rave-portal-resources/src/main/webapp/css/default.css Wed Nov  9
02:28:39 2011
@@ -139,6 +139,10 @@ header h1 {
     color: #F2F2F2;
 }
 
+.header-mobile {
+    height:auto;
+}
+
 .topnav {
     float: right;
     margin-right: 2%;
@@ -189,6 +193,12 @@ header h1 {
     height: 100%;
 }
 
+.widget-mobile {
+    box-shadow: none;
+    border-radius: 0 0 0 0;    
+    padding: 0 0 0 0;
+}
+
 .widget-wrapper-transitional {
     position: absolute;
     z-index: 1000;
@@ -220,6 +230,10 @@ header h1 {
     margin-bottom: 20px;
 }
 
+.widget-wrapper-mobile {
+    margin-bottom: 3px;
+}
+
 .widget-title-bar {
     color: #FFFFFF;
     filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#999999", endColorstr="#666666");
@@ -235,6 +249,14 @@ header h1 {
     cursor: move;
 }
 
+.widget-title-bar-mobile {
+    border-radius: 0 0 0 0;
+}
+
+.widget-title-bar-mobile:hover {
+    cursor: pointer;
+}
+
 .widget-title {
     display: inline;
 }
@@ -289,12 +311,20 @@ header h1 {
     float: left;
     display: block;
     padding: 5px 5px 100px 5px; /*** bottom padding is needed for dnd when region is empty
***/
-    margin-right: 20px;
-    min-width:300px;
+    margin-right: 20px;
+    min-width:300px;
     width: auto;
     height: 100%;
 }
 
+.region-mobile {
+    display: block;
+    width: 100%;
+    padding: 0px 0px 0px 0px;
+    margin-right: 0px;        
+    float: none;
+}
+
 .region-dragging {
     height: 200%;
     min-width: 250px;
@@ -514,6 +544,34 @@ span.error, label.error {
     font-weight: bold;
 }
 
+.rave-ui-tab-mobile {
+    border: none;
+    background-color: #FFFFFF;    
+    color: #767676;
+    font-weight: normal;
+    font-style: normal;
+}
+
+.rave-ui-tab-mobile a, .rave-ui-tab-mobile a:visited {
+    color: #767676;
+    text-decoration: none;
+}
+
+.rave-ui-tab-mobile:hover, .rave-ui-tab-mobile a:hover {
+    color: #000000;
+    border: none;    
+    background-color: #FFFFFF;
+}
+
+.rave-ui-tab-selected-mobile, .rave-ui-tab-selected-mobile:hover {
+    border: 1px solid #B4C4CF;
+    border-bottom: 1px solid #FFFFFF;
+    background-color: #FFFFFF;        
+    color: #000000;
+    font-style: normal;
+    font-weight: bold;
+}
+
 #dialog {
     width:400px;
     display: none;
@@ -539,6 +597,12 @@ span.error, label.error {
     background: -webkit-gradient(linear, left top, left bottom, from(#D7D7D3), to(#EBEBEB));
 }
 
+.pageContent-mobile {
+    background: none !important;
+    background-color: #FFFFFF !important;
+    margin-top: 3px;
+}
+
 .page-title {
     display: inline-block;
     padding: 5px 10px;

Modified: incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave.js?rev=1199600&r1=1199599&r2=1199600&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave.js (original)
+++ incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave.js Wed Nov  9 02:28:39
2011
@@ -60,6 +60,10 @@ var rave = rave || (function() {
         var WIDGET_TOGGLE_DISPLAY_COLLAPSED = "ui-icon-triangle-1-e";
         var WIDGET_TOGGLE_DISPLAY_NORMAL = "ui-icon-triangle-1-s";             
 
+        // variable to store whether or not the 
+        // client is a mobile device
+        var mobileState = false;
+
         function WIDGET_PREFS_EDIT_BUTTON(regionWidgetId) {
             return "widget-" + regionWidgetId + "-prefs";
         }
@@ -83,6 +87,14 @@ var rave = rave || (function() {
             targetIndex: null
         };
 
+        function setMobileState(mobileState) {
+            this.mobileState = mobileState;
+        }
+
+        function getMobileState() {
+            return this.mobileState;
+        }
+
         function init() {
             // initialize the sortable regions
             $(".region").sortable({
@@ -140,6 +152,24 @@ var rave = rave || (function() {
                 styleWidgetButtons(widgetId);
             });
         }
+        
+        function initMobileWidgetUI() {
+            $(".widget-wrapper").each(function(){
+                var widgetId = extractObjectIdFromElementId($(this).attr("id"));        
       
+                var widget = rave.getWidgetById(widgetId);
+                            
+                // init the collapse/restore toggle for the title bar                
+                $(this).find(".widget-title-bar-mobile").click({id: widgetId}, toggleCollapseAction);

+                $(this).find(".widget-title-bar-mobile").bind( "touchstart", function(e){alert('Span
Clicked!')});
+            });
+        }
+        
+        function toggleMobileWidget(regionWidgetId) {
+            var args = {};
+            args.data = {};            
+            args.data.id = regionWidgetId;
+            toggleCollapseAction(args);
+        }
 
         function maximizeAction(args) {
             var regionWidgetId = args.data.id;            
@@ -205,9 +235,31 @@ var rave = rave || (function() {
                 }
             }
             
-            rave.api.rest.saveWidgetCollapsedState(functionArgs);           
+            // don't persist the collapse / restore state if we are in 
+            // mobile mode because we defaulted all widgets to collapsed
+            // when initially rendering the mobile view
+            if (rave.isMobile()) {
+                rave.doWidgetUiCollapse(functionArgs);           
+            } else {
+                rave.api.rest.saveWidgetCollapsedState(functionArgs);           
+            }
         }      
         
+        function doWidgetUiCollapse(args) {
+            // update the in-memory widget with the new collapsed status
+            rave.getWidgetById(args.regionWidgetId).collapsed = args.collapsed;
+
+            // toggle the collapse/restore icon
+            rave.toggleCollapseWidgetIcon(args.regionWidgetId);
+
+            // if the widget has supplied a collapse or restore 
+            // function, invoke it so each widget provider
+            // can handle the collapse / restore action independently
+            if (typeof args.successCallback == 'function') {
+                args.successCallback();
+            }
+        }
+        
         /**
          * Utility function to generate the html label for a userPref
          * based on if it is required or not
@@ -479,11 +531,16 @@ var rave = rave || (function() {
         }   
 
         return {
-          init : init,          
+          init : init,       
+          initMobile: initMobileWidgetUI,
           toggleCollapseWidgetIcon: toggleCollapseWidgetIcon,
           maximizeAction: maximizeAction,
           minimizeAction: minimizeAction,
-          editPrefsAction: editPrefsAction
+          editPrefsAction: editPrefsAction,
+          setMobileState: setMobileState,
+          getMobileState: getMobileState,
+          doWidgetUiCollapse: doWidgetUiCollapse,
+          toggleMobileWidget: toggleMobileWidget
         };
 
     })();
@@ -515,13 +572,20 @@ var rave = rave || (function() {
         //However this should at least get us to render the top "row" first, then the second
"row", ... in any browser.
         //If this turns out to be a major concern we can change the widgetsByRegionIdMap
to a 2D array instead of a map.
         var widgets = [];
+        var regionWidget;
         for (var i = 0; ; i++) {
             var foundGadgets = false;
             for (var regionWidgets in widgetsByRegionIdMap) {
                 regionWidgets = widgetsByRegionIdMap[regionWidgets];
                 if (regionWidgets.length > i) {
                     foundGadgets = true;
-                    widgets.push(regionWidgets[i]);
+                    regionWidget = regionWidgets[i];
+                    // if client is viewing in mobile mode
+                    // default to collapsed state
+                    if (rave.isMobile()) {
+                        regionWidget.collapsed = true;
+                    }
+                    widgets.push(regionWidget);
                 }
             }
 
@@ -621,6 +685,10 @@ var rave = rave || (function() {
          * Initialize Rave's drag and drop facilities
          */
         initUI : ui.init,
+        /**
+         * Initialize the mobile UI
+         */
+        initMobileUI : ui.initMobile,
 
         /**
          * Parses the given string conforming to a rave object's DOM element ID and return
@@ -711,6 +779,28 @@ var rave = rave || (function() {
          * @param regionWidgetId the regionWidgetId of the widget
          * 
          */
-        editPrefs: ui.editPrefsAction
+        editPrefs: ui.editPrefsAction,
+        /***
+         * Get the mobile state - used by the UI to render mobile or normal content
+         * 
+         */                
+        isMobile: ui.getMobileState,
+        /***
+         * Set the mobile state - used by the UI to render mobile or normal content
+         * 
+         * @param mobileState boolean to represent the mobile state
+         * 
+         */        
+        setMobile: ui.setMobileState,
+        /**
+         * Performs the client side work of collapsing/restoring a widget
+         * @param args
+         */
+        doWidgetUiCollapse: ui.doWidgetUiCollapse,
+        /**
+         * Toggles a mobile widget collapse/restore
+         * @param args
+         */
+        toggleMobileWidget: ui.toggleMobileWidget
     }
 })();

Modified: incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave_api.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave_api.js?rev=1199600&r1=1199599&r2=1199600&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave_api.js (original)
+++ incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave_api.js Wed Nov
 9 02:28:39 2011
@@ -74,19 +74,10 @@ rave.api = rave.api || (function() {
                 data: JSON.stringify(args.collapsed),  
                 contentType: 'application/json',
                 dataType: 'json',
-                success: function(result) {
-                    // update the in-memory widget with the new collapsed status
-                    rave.getWidgetById(result.entityId).collapsed = result.collapsed;
-                    
-                    // toggle the collapse/restore icon
-                    rave.toggleCollapseWidgetIcon(result.entityId);
-                    
-                    // if the widget has supplied a collapse or restore 
-                    // callback function, invoke it so each widget provider
-                    // can handle the collapse / restore action independently
-                    if (typeof args.successCallback == 'function') {
-                        args.successCallback();
-                    }
+                success: function(result) {                    
+                    rave.doWidgetUiCollapse({"regionWidgetId": result.entityId, 
+                                             "collapsed": result.collapsed, 
+                                             "successCallback": args.successCallback}); 
                  
                 },
                 error: handleError
             });                        



Mime
View raw message