Committing patch for RAVE-1024

git-svn-id: https://svn.apache.org/repos/asf/rave/trunk@1539471 
13f79535-47bb-0310-9956-ffa450edef68


Project: http://git-wip-us.apache.org/repos/asf/rave/repo
Commit: http://git-wip-us.apache.org/repos/asf/rave/commit/dd45b769
Tree: http://git-wip-us.apache.org/repos/asf/rave/tree/dd45b769
Diff: http://git-wip-us.apache.org/repos/asf/rave/diff/dd45b769

Branch: refs/heads/angular
Commit: dd45b7699c690ff62add9b3a98257b1ff4c19775
Parents: 8277733
Author: Matthew B. Franklin <[email protected]>
Authored: Wed Nov 6 21:46:34 2013 +0000
Committer: Matthew B. Franklin <[email protected]>
Committed: Wed Nov 6 21:46:34 2013 +0000

----------------------------------------------------------------------
 .../main/java/org/apache/rave/model/Page.java   |  17 ++++
 .../java/org/apache/rave/rest/model/Page.java   |  12 +++
 .../apache/rave/portal/model/impl/PageImpl.java |  12 +++
 .../apache/rave/portal/service/PageService.java |  20 ++++
 .../portal/service/impl/DefaultPageService.java |  15 ++-
 .../rave/rest/impl/DefaultPageResource.java     |   3 +-
 .../service/impl/DefaultPageServiceTest.java    |  35 ++++++-
 .../org/apache/rave/portal/model/JpaPage.java   |  41 +++++++-
 .../model/conversion/JpaPageConverter.java      |   1 +
 .../repository/impl/JpaPageRepository.java      | 102 +++++++++++++------
 .../model/conversion/JpaPageConverterTest.java  |   3 +
 .../repository/impl/JpaPageRepositoryTest.java  |  24 +++++
 .../conversion/impl/MongoDbPageConverter.java   |   1 +
 13 files changed, 245 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/rave/blob/dd45b769/rave-components/rave-core-api/src/main/java/org/apache/rave/model/Page.java
----------------------------------------------------------------------
diff --git 
a/rave-components/rave-core-api/src/main/java/org/apache/rave/model/Page.java 
b/rave-components/rave-core-api/src/main/java/org/apache/rave/model/Page.java
index d06cc28..dcefdd5 100644
--- 
a/rave-components/rave-core-api/src/main/java/org/apache/rave/model/Page.java
+++ 
b/rave-components/rave-core-api/src/main/java/org/apache/rave/model/Page.java
@@ -20,6 +20,7 @@ package org.apache.rave.model;
 
 import javax.xml.bind.annotation.XmlTransient;
 import java.util.List;
+import java.util.Map;
 
 @XmlTransient
 public interface Page {
@@ -63,4 +64,20 @@ public interface Page {
 
     List<PageUser> getMembers();
     void setMembers(List<PageUser> members);
+
+    /**
+     * Generic property bag for extension of the page object.
+     *
+     * Rave makes no attempt to understand the shape of the property bag.
+     *
+     * @return a valid Map of String to Object.
+     */
+    Map<String, Object> getProperties();
+
+    /**
+     * Overrides the current properties with a new set.
+     *
+     * @param properties a non-null map of string to JSON serializable object
+     */
+    void setProperties(Map<String, Object> properties);
 }

http://git-wip-us.apache.org/repos/asf/rave/blob/dd45b769/rave-components/rave-core-api/src/main/java/org/apache/rave/rest/model/Page.java
----------------------------------------------------------------------
diff --git 
a/rave-components/rave-core-api/src/main/java/org/apache/rave/rest/model/Page.java
 
b/rave-components/rave-core-api/src/main/java/org/apache/rave/rest/model/Page.java
index 0dce30a..55e395a 100644
--- 
a/rave-components/rave-core-api/src/main/java/org/apache/rave/rest/model/Page.java
+++ 
b/rave-components/rave-core-api/src/main/java/org/apache/rave/rest/model/Page.java
@@ -22,6 +22,7 @@ package org.apache.rave.rest.model;
 import javax.xml.bind.annotation.*;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "Page", propOrder = {
@@ -40,6 +41,8 @@ public class Page  implements RestEntity{
     private String pageType;
     @XmlElement(name="pageLayoutCode")
     private String pageLayoutCode;
+    @XmlElement(name="properties")
+    private Map<String, Object> properties;
     @XmlElementWrapper(name = "subPages")
     @XmlElement(name="Page")
     private List<Page> subPages;
@@ -58,6 +61,7 @@ public class Page  implements RestEntity{
         this.ownerId = source.getOwnerId();
         this.pageType = source.getPageType().toString();
         this.pageLayoutCode = source.getPageLayout().getCode();
+        this.properties = source.getProperties();
         this.subPages = createSubPages(source);
         this.regions = createRegions(source);
         this.members = createPageUsers(source);
@@ -103,6 +107,14 @@ public class Page  implements RestEntity{
         this.pageLayoutCode = pageLayoutCode;
     }
 
+    public Map<String, Object> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(Map<String, Object> properties) {
+        this.properties = properties;
+    }
+
     public List<Page> getSubPages() {
         return subPages;
     }

http://git-wip-us.apache.org/repos/asf/rave/blob/dd45b769/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageImpl.java
----------------------------------------------------------------------
diff --git 
a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageImpl.java
 
b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageImpl.java
index f203117..c14790e 100644
--- 
a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageImpl.java
+++ 
b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageImpl.java
@@ -21,6 +21,7 @@ package org.apache.rave.portal.model.impl;
 import org.apache.rave.model.*;
 
 import java.util.List;
+import java.util.Map;
 
 public class PageImpl implements Page {
     private String id;
@@ -33,6 +34,7 @@ public class PageImpl implements Page {
     private List<Region> regions;
     private String pageType;
     private List<PageUser> members;
+    private Map<String, Object> properties;
 
     public PageImpl() {}
 
@@ -146,6 +148,16 @@ public class PageImpl implements Page {
     }
 
     @Override
+    public Map<String, Object> getProperties() {
+        return properties;
+    }
+
+    @Override
+    public void setProperties(Map<String, Object> properties) {
+        this.properties = properties;
+    }
+
+    @Override
     public boolean equals(Object obj) {
         if (obj == null) {
             return false;

http://git-wip-us.apache.org/repos/asf/rave/blob/dd45b769/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/PageService.java
----------------------------------------------------------------------
diff --git 
a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/PageService.java
 
b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/PageService.java
index a073bc8..fadb17b 100644
--- 
a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/PageService.java
+++ 
b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/PageService.java
@@ -27,6 +27,7 @@ import org.springframework.security.access.prepost.PostFilter;
 import org.springframework.security.access.prepost.PreAuthorize;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author carlucci
@@ -240,6 +241,8 @@ public interface PageService {
     @PreAuthorize("hasPermission(#regionWidgetId, 
'org.apache.rave.model.RegionWidget', 'delete')")
     Region removeWidgetFromPage(String regionWidgetId);
 
+    //TODO re-design update methodology to support a wider set of properties 
and re-collapse to a single method
+
     /**
      * Updates the page properties.
      *
@@ -250,6 +253,23 @@ public interface PageService {
     @PreAuthorize("hasPermission(#pageId, 'org.apache.rave.model.Page', 
'update')")
     Page updatePage(String pageId, String name, String pageLayoutCode);
 
+    //There are cases where we need to update more than just hte name & 
layout, but those need to be thought through.
+    //Properties are intended to be managed by the client and to Rave is an 
opaque data bag.  Rather than re-design the entire
+    //page update methodology as part of adding properties, this addition 
allows us to update properties from the client
+    //without making breaking changes to existing code or page mutability 
assumptions.
+    /**
+     * Updates the page properties.
+     *
+     * @param pageId         the id of the page to update
+     * @param name           the new name for the page
+     * @param pageLayoutCode the new layout for the page
+     * @param properties     the properties of the page to set.  MUST NOT be 
null. To clear properties, call with empty map.
+     */
+    @PreAuthorize("hasPermission(#pageId, 'org.apache.rave.model.Page', 
'update')")
+    Page updatePage(String pageId, String name, String pageLayoutCode, 
Map<String, Object> properties);
+
+    //END TODO
+
     /**
      * Moves a page to be rendered after another page in order for a user
      *

http://git-wip-us.apache.org/repos/asf/rave/blob/dd45b769/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java
----------------------------------------------------------------------
diff --git 
a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java
 
b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java
index 27c1ffc..c6f774a 100644
--- 
a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java
+++ 
b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java
@@ -42,6 +42,7 @@ import 
org.springframework.transaction.annotation.Transactional;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 @Service
 public class DefaultPageService implements PageService {
@@ -330,6 +331,12 @@ public class DefaultPageService implements PageService {
     @Override
     @Transactional
     public Page updatePage(String pageId, String name, String pageLayoutCode) {
+        return updatePage(pageId, name, pageLayoutCode, null);
+    }
+
+    @Override
+    @Transactional
+    public Page updatePage(String pageId, String name, String pageLayoutCode, 
Map<String, Object> properties) {
         Page page = pageRepository.get(pageId);
         PageLayout newLayout = 
pageLayoutRepository.getByPageLayoutCode(pageLayoutCode);
         PageLayout curLayout = page.getPageLayout();
@@ -352,9 +359,11 @@ public class DefaultPageService implements PageService {
         //save the new page properties
         page.setName(name);
         page.setPageLayout(newLayout);
-        pageRepository.save(page);
-
-        return page;
+        //Forces callers to send an empty map rather than a null value to 
clear properties
+        if(properties != null) {
+            page.setProperties(properties);
+        }
+        return pageRepository.save(page);
     }
 
     @Transactional

http://git-wip-us.apache.org/repos/asf/rave/blob/dd45b769/rave-components/rave-core/src/main/java/org/apache/rave/rest/impl/DefaultPageResource.java
----------------------------------------------------------------------
diff --git 
a/rave-components/rave-core/src/main/java/org/apache/rave/rest/impl/DefaultPageResource.java
 
b/rave-components/rave-core/src/main/java/org/apache/rave/rest/impl/DefaultPageResource.java
index 1c4ad9e..79a40e1 100644
--- 
a/rave-components/rave-core/src/main/java/org/apache/rave/rest/impl/DefaultPageResource.java
+++ 
b/rave-components/rave-core/src/main/java/org/apache/rave/rest/impl/DefaultPageResource.java
@@ -102,7 +102,8 @@ public class DefaultPageResource implements PagesResource {
             throw new BadRequestException("Page pageLayoutCode property must 
be defined.");
         }
         //TODO: a bad page layout code can corrupt the data
-        org.apache.rave.model.Page fromDb = pageService.updatePage(id, 
page.getName(), page.getPageLayoutCode());
+        //As part of the model refactor, this needs to be made more concise 
and clear what properties of a page are mutable and why
+        org.apache.rave.model.Page fromDb = pageService.updatePage(id, 
page.getName(), page.getPageLayoutCode(), page.getProperties());
         Page responsePage = new Page(fromDb);
 
         return responsePage;

http://git-wip-us.apache.org/repos/asf/rave/blob/dd45b769/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPageServiceTest.java
----------------------------------------------------------------------
diff --git 
a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPageServiceTest.java
 
b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPageServiceTest.java
index 0ddc5ea..e419112 100644
--- 
a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPageServiceTest.java
+++ 
b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPageServiceTest.java
@@ -20,6 +20,7 @@
 package org.apache.rave.portal.service.impl;
 
 import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import org.apache.rave.model.Page;
 import org.apache.rave.model.PageLayout;
 import org.apache.rave.model.PageTemplate;
@@ -52,6 +53,7 @@ import org.junit.Test;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import static org.easymock.EasyMock.*;
 import static org.hamcrest.CoreMatchers.equalTo;
@@ -736,7 +738,7 @@ public class DefaultPageServiceTest {
 
         RegionWidget instance = pageService.addWidgetToPage(PAGE_ID, 
WIDGET_ID);
 
-        verify(pageRepository,regionRepository,widgetRepository);
+        verify(pageRepository, regionRepository, widgetRepository);
 
         verifyPositions(0, instance, true);
         assertThat(originalRegion.getRegionWidgets().get(0), 
is(sameInstance(instance)));
@@ -973,6 +975,37 @@ public class DefaultPageServiceTest {
     }
 
     @Test
+    public void updatePage_properties() {
+        String newName = "new page name";
+        String layoutName = "layout name";
+        Map<String, Object> props = Maps.newHashMap();
+
+        PageLayoutImpl layout = createStrictMock(PageLayoutImpl.class);
+        
expect(layout.getNumberOfRegions()).andReturn(Long.valueOf(2L)).anyTimes();
+        replay(layout);
+
+        //create a strict mock that ensures that the appropriate setters are
+        //called, rather than checking the return value from the function
+        Page curPage = createStrictMock(PageImpl.class);
+        expect(curPage.getPageLayout()).andReturn(layout);
+        curPage.setName(newName);
+        curPage.setPageLayout(layout);
+        curPage.setProperties(props);
+        replay(curPage);
+
+        expect(pageRepository.get(PAGE_ID)).andReturn(curPage);
+        expect(pageRepository.save(curPage)).andReturn(curPage);
+        replay(pageRepository);
+
+        
expect(pageLayoutRepository.getByPageLayoutCode(layoutName)).andReturn(layout);
+        replay(pageLayoutRepository);
+
+        pageService.updatePage(PAGE_ID, newName, layoutName, props);
+
+        verify(curPage);
+    }
+
+    @Test
     public void updatePage_addRegion() {
         String newName = "new page name";
         String layoutName = "layout name";

http://git-wip-us.apache.org/repos/asf/rave/blob/dd45b769/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPage.java
----------------------------------------------------------------------
diff --git 
a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPage.java
 
b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPage.java
index 8dd0177..462dd8c 100644
--- 
a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPage.java
+++ 
b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPage.java
@@ -18,18 +18,17 @@
  */
 package org.apache.rave.portal.model;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonManagedReference;
 import org.apache.rave.model.*;
 import org.apache.rave.portal.model.conversion.ConvertingListProxyFactory;
 import org.apache.rave.portal.model.conversion.JpaConverter;
+import org.apache.rave.util.JsonUtils;
 
 import javax.persistence.*;
 import javax.xml.bind.annotation.*;
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
+import java.util.*;
 
 /**
  * A page, which consists of regions, and which may be owned by a {@link 
JpaUser} (note the ownership will likely need to
@@ -50,6 +49,7 @@ import java.util.List;
         @NamedQuery(name = JpaPage.GET_COUNT, query="SELECT count(p) FROM 
JpaPage p"),
         @NamedQuery(name = JpaPage.DELETE_BY_USER_ID_AND_PAGE_TYPE, 
query="DELETE FROM JpaPage p WHERE p.ownerId = :userId and p.pageType = 
:pageType"),
         @NamedQuery(name = JpaPage.USER_HAS_PERSON_PAGE, query="SELECT 
count(p) FROM JpaPage p WHERE p.ownerId = :userId and p.pageType = :pageType"),
+        @NamedQuery(name = JpaPage.HAS_CONTEXT_PAGE, query="SELECT count(p) 
FROM JpaPage p WHERE p.contextId = :contextId and p.pageType = :pageType"),
         @NamedQuery(name = JpaPage.GET_BY_CONTEXT_AND_PAGE_TYPE, query="SELECT 
p FROM JpaPage p WHERE p.contextId = :contextId and p.pageType = :pageType")
 })
 @Access(AccessType.FIELD)
@@ -60,6 +60,7 @@ public class JpaPage implements BasicEntity, Serializable, 
Page {
     public static final String USER_HAS_PERSON_PAGE = "JpaPage.hasPersonPage";
     public static final String GET_ALL = "JpaPage.getAll";
     public static final String GET_COUNT = "JpaPage.getCount";
+    public static final String HAS_CONTEXT_PAGE = "JpaPage.hasContextPage";
     public static final String GET_BY_CONTEXT_AND_PAGE_TYPE = 
"JpaPage.getByContextAndPageType";
 
     @XmlAttribute(name="id")
@@ -105,6 +106,14 @@ public class JpaPage implements BasicEntity, Serializable, 
Page {
     @OneToMany(targetEntity=JpaPageUser.class, fetch = FetchType.EAGER, 
cascade = CascadeType.ALL, mappedBy="page", orphanRemoval=true)
     private List<JpaPageUser> members;
 
+    @Lob @JsonIgnore
+    @Column(name = "serialized_data")
+    private String serializedData;
+
+    //It will be the responsibility of the repository to ensure that this 
property is set when the page is retrieved from the database
+    @Transient
+    private Map<String, Object> properties;
+
 
     public JpaPage() {
     }
@@ -294,6 +303,16 @@ public class JpaPage implements BasicEntity, Serializable, 
Page {
     }
 
     @Override
+    public Map<String, Object> getProperties() {
+        return properties;
+    }
+
+    @Override
+    public void setProperties(Map<String, Object> properties) {
+        this.properties = properties;
+    }
+
+    @Override
     public boolean equals(Object obj) {
         if (obj == null) {
             return false;
@@ -320,6 +339,20 @@ public class JpaPage implements BasicEntity, Serializable, 
Page {
         return "Page{" + "entityId=" + entityId + ", name=" + name + ", 
ownerId=" + ownerId + ", pageLayout=" + pageLayout + ", pageType=" + pageType + 
"}";
     }
 
+    public void serializeData() {
+        Map<String, Object> properties = this.getProperties();
+        if(properties != null) {
+            serializedData = JsonUtils.stringify(properties);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void deserializeData() {
+        if(serializedData != null) {
+            this.setProperties(JsonUtils.parse(serializedData, Map.class));
+        }
+    }
+
     /**
      * Comparator used to sort sub pages.  It looks for PageUser objects 
representing the sub pages that are owned
      * by the parent page user, and uses the renderSequence as the sorting 
field

http://git-wip-us.apache.org/repos/asf/rave/blob/dd45b769/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageConverter.java
----------------------------------------------------------------------
diff --git 
a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageConverter.java
 
b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageConverter.java
index c3a409c..dc8ab03 100644
--- 
a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageConverter.java
+++ 
b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageConverter.java
@@ -72,6 +72,7 @@ public class JpaPageConverter implements ModelConverter<Page, 
JpaPage> {
         converted.setParentPage(source.getParentPage());
         converted.setRegions(source.getRegions());
         converted.setSubPages(source.getSubPages());
+        converted.setProperties(source.getProperties());
     }
 
     private void replacePageReferences(Page source, JpaPage converted) {

http://git-wip-us.apache.org/repos/asf/rave/blob/dd45b769/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPageRepository.java
----------------------------------------------------------------------
diff --git 
a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPageRepository.java
 
b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPageRepository.java
index 989809a..db374c3 100644
--- 
a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPageRepository.java
+++ 
b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPageRepository.java
@@ -19,20 +19,21 @@
 
 package org.apache.rave.portal.repository.impl;
 
+import org.apache.commons.lang3.StringUtils;
+import org.apache.rave.exception.DataSerializationException;
 import org.apache.rave.model.*;
 import org.apache.rave.portal.model.*;
 import org.apache.rave.portal.model.conversion.JpaPageConverter;
 import org.apache.rave.portal.repository.PageRepository;
 import org.apache.rave.util.CollectionUtils;
+import org.apache.rave.util.JsonUtils;
+import org.json.JSONException;
+import org.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.Query;
-import javax.persistence.TypedQuery;
-import java.util.ArrayList;
-import java.util.List;
+import javax.persistence.*;
+import java.util.*;
 
 import static org.apache.rave.persistence.jpa.util.JpaUtil.getPagedResultList;
 import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;
@@ -53,12 +54,13 @@ public class JpaPageRepository implements PageRepository {
 
     @Override
     public Page get(String id) {
-        return manager.find(JpaPage.class, Long.parseLong(id));
+        return expandProperties(manager.find(JpaPage.class, 
Long.parseLong(id)));
     }
 
     @Override
     public Page save(Page item) {
         JpaPage page = pageConverter.convert(item);
+        page.serializeData();
         return saveOrUpdate(page.getEntityId(), manager, page);
     }
 
@@ -80,7 +82,7 @@ public class JpaPageRepository implements PageRepository {
         TypedQuery<JpaPage> query = 
manager.createNamedQuery(JpaPageUser.GET_BY_USER_ID_AND_PAGE_TYPE, 
JpaPage.class);
         query.setParameter("userId", userId);
         query.setParameter("pageType", pageType.toUpperCase());
-        return CollectionUtils.<Page>toBaseTypedList(query.getResultList());
+        return 
expandProperties(CollectionUtils.<Page>toBaseTypedList(query.getResultList()));
     }
 
     @Override
@@ -88,7 +90,7 @@ public class JpaPageRepository implements PageRepository {
         TypedQuery<JpaPage> query = 
manager.createNamedQuery(JpaPage.GET_BY_CONTEXT_AND_PAGE_TYPE, JpaPage.class);
         query.setParameter("contextId", contextId);
         query.setParameter("pageType", pageType.toUpperCase());
-        return CollectionUtils.<Page>toBaseTypedList(query.getResultList());
+        return 
expandProperties(CollectionUtils.<Page>toBaseTypedList(query.getResultList()));
     }
 
     @Override
@@ -126,8 +128,11 @@ public class JpaPageRepository implements PageRepository {
     }
 
     @Override
-    public boolean hasPage(String userId, String pageType) {
-        return false;  //To change body of implemented methods use File | 
Settings | File Templates.
+    public boolean hasPage(String contextId, String pageType) {
+        TypedQuery<Long> query = 
manager.createNamedQuery(JpaPage.HAS_CONTEXT_PAGE, Long.class);
+        query.setParameter("contextId", contextId);
+        query.setParameter("pageType", pageType);
+        return query.getSingleResult() > 0;
     }
 
     @Override
@@ -135,7 +140,7 @@ public class JpaPageRepository implements PageRepository {
         TypedQuery<JpaPageUser> query = 
manager.createNamedQuery(JpaPageUser.GET_PAGES_FOR_USER, JpaPageUser.class);
         query.setParameter("userId", userId);
         query.setParameter("pageType", pageType.toUpperCase());
-        return 
CollectionUtils.<PageUser>toBaseTypedList(query.getResultList());
+        return 
expandPageUserProperties(CollectionUtils.<PageUser>toBaseTypedList(query.getResultList()));
     }
 
     @Override
@@ -143,7 +148,7 @@ public class JpaPageRepository implements PageRepository {
         TypedQuery<JpaPageUser> query = 
manager.createNamedQuery(JpaPageUser.GET_SINGLE_RECORD, JpaPageUser.class);
         query.setParameter("userId", userId);
         query.setParameter("pageId", pageId == null ? null : 
Long.parseLong(pageId));
-        return query.getSingleResult();
+        return expandPageUserProperties(query.getSingleResult());
     }
 
     @Override
@@ -151,6 +156,25 @@ public class JpaPageRepository implements PageRepository {
         return convert(pt, user);
     }
 
+    @Override
+    public List<Page> getAll() {
+        TypedQuery<Page> query = manager.createNamedQuery(JpaPage.GET_ALL, 
Page.class);
+        return 
expandProperties(CollectionUtils.<Page>toBaseTypedList(query.getResultList()));
+    }
+
+    @Override
+    public List<Page> getLimitedList(int offset, int limit) {
+        TypedQuery<Page> query = manager.createNamedQuery(JpaPage.GET_ALL, 
Page.class);
+        return 
expandProperties(CollectionUtils.<Page>toBaseTypedList(getPagedResultList(query,
 offset, limit)));
+    }
+
+    @Override
+    public int getCountAll() {
+        Query query = manager.createNamedQuery(JpaPage.GET_COUNT);
+        Number countResult = (Number) query.getSingleResult();
+        return countResult.intValue();
+    }
+
     private void removePageUsers(JpaPage item) {
         for(PageUser user : item.getMembers()) {
             user.setPage(null);
@@ -160,6 +184,39 @@ public class JpaPageRepository implements PageRepository {
         }
     }
 
+    private JpaPage expandProperties(JpaPage page) {
+        if(page != null) {
+            page.deserializeData();
+        }
+        return page;
+    }
+
+    private List<Page> expandProperties(List<Page> pages) {
+        for(Page page : pages) {
+            if(page instanceof JpaPage){
+                expandProperties((JpaPage)page);
+            }
+        }
+        return pages;
+    }
+
+    private JpaPageUser expandPageUserProperties(JpaPageUser pageUser) {
+        Page page = pageUser.getPage();
+        if(page != null && page instanceof JpaPage) {
+            ((JpaPage)page).deserializeData();
+        }
+        return pageUser;
+    }
+
+    private List<PageUser> expandPageUserProperties(List<PageUser> pageUsers) {
+        for(PageUser page : pageUsers) {
+            if(page instanceof JpaPageUser) {
+                expandPageUserProperties((JpaPageUser)page);
+            }
+        }
+        return pageUsers;
+    }
+
     /**
      * convert: PageTemplate, User -> Page
      * Converts the PageTemplate for Person Profiles into a Person Profile Page
@@ -267,23 +324,4 @@ public class JpaPageRepository implements PageRepository {
         }
         return pages;
     }
-
-    @Override
-    public List<Page> getAll() {
-        TypedQuery<Page> query = manager.createNamedQuery(JpaPage.GET_ALL, 
Page.class);
-        return CollectionUtils.<Page>toBaseTypedList(query.getResultList());
-    }
-
-    @Override
-    public List<Page> getLimitedList(int offset, int limit) {
-        TypedQuery<Page> query = manager.createNamedQuery(JpaPage.GET_ALL, 
Page.class);
-        return CollectionUtils.<Page>toBaseTypedList(getPagedResultList(query, 
offset, limit));
-    }
-
-    @Override
-    public int getCountAll() {
-        Query query = manager.createNamedQuery(JpaPage.GET_COUNT);
-        Number countResult = (Number) query.getSingleResult();
-        return countResult.intValue();
-    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/rave/blob/dd45b769/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageConverterTest.java
----------------------------------------------------------------------
diff --git 
a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageConverterTest.java
 
b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageConverterTest.java
index b734a90..4810a92 100644
--- 
a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageConverterTest.java
+++ 
b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageConverterTest.java
@@ -32,6 +32,7 @@ import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 
 import static org.hamcrest.CoreMatchers.*;
 import static org.junit.Assert.assertThat;
@@ -68,6 +69,7 @@ public class JpaPageConverterTest {
         page.setParentPage(new PageImpl("1"));
         page.setRegions(new ArrayList<Region>());
         page.setSubPages(new ArrayList<Page>());
+        page.setProperties(new HashMap<String, Object>());
 
         JpaPage converted = pageConverter.convert(page);
         assertThat(converted, is(not(sameInstance(page))));
@@ -82,5 +84,6 @@ public class JpaPageConverterTest {
         assertThat(converted.getPageLayout().getCode(), 
is(equalTo(page.getPageLayout().getCode())));
         assertThat(converted.getPageType(), is(equalTo(page.getPageType())));
         assertThat(converted.getSubPages(), is(equalTo(page.getSubPages())));
+        assertThat(converted.getProperties(), 
is(equalTo(page.getProperties())));
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/rave/blob/dd45b769/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPageRepositoryTest.java
----------------------------------------------------------------------
diff --git 
a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPageRepositoryTest.java
 
b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPageRepositoryTest.java
index 2f31dfc..437204b 100644
--- 
a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPageRepositoryTest.java
+++ 
b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPageRepositoryTest.java
@@ -37,7 +37,9 @@ import 
org.springframework.transaction.annotation.Transactional;
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import static org.hamcrest.CoreMatchers.*;
 import static org.junit.Assert.*;
@@ -291,6 +293,28 @@ public class JpaPageRepositoryTest {
         assertEquals(user.getId(), subPage2.getOwnerId());
     }
 
+
+    @Test
+    @Transactional(readOnly = false)
+    @Rollback(true)
+    public void createPageWithProperties(){
+        Page page = new PageImpl(null, USER_ID);
+        page.setName("FOO");
+        HashMap<String, Object> objectHashMap = new HashMap<String, Object>();
+        HashMap<String, Object> subObject = new HashMap<String, Object>();
+        objectHashMap.put("context", subObject);
+        subObject.put("foo", "bar");
+        page.setProperties(objectHashMap);
+
+        Page fromDb = repository.save(page);
+        //Go and get it again to make sure it is coming from the db
+        fromDb = repository.get(fromDb.getId());
+        Map<String,Object> properties = fromDb.getProperties();
+        assertThat(properties, is(not(nullValue())));
+        assertThat(properties.get("context"), is(instanceOf(Map.class)));
+        assertThat(((Map)properties.get("context")).get("foo"), 
is(equalTo((Object)"bar")));
+    }
+
     @Test
     public void hasPersonPage_true(){
         assertTrue(repository.hasPersonPage(USER_ID));

http://git-wip-us.apache.org/repos/asf/rave/blob/dd45b769/rave-components/rave-mongodb/src/main/java/org/apache/rave/portal/model/conversion/impl/MongoDbPageConverter.java
----------------------------------------------------------------------
diff --git 
a/rave-components/rave-mongodb/src/main/java/org/apache/rave/portal/model/conversion/impl/MongoDbPageConverter.java
 
b/rave-components/rave-mongodb/src/main/java/org/apache/rave/portal/model/conversion/impl/MongoDbPageConverter.java
index 6d9e994..04ffaef 100644
--- 
a/rave-components/rave-mongodb/src/main/java/org/apache/rave/portal/model/conversion/impl/MongoDbPageConverter.java
+++ 
b/rave-components/rave-mongodb/src/main/java/org/apache/rave/portal/model/conversion/impl/MongoDbPageConverter.java
@@ -54,6 +54,7 @@ public class MongoDbPageConverter implements 
HydratingModelConverter<Page, Mongo
         page.setOwnerId(sourcePage.getOwnerId());
         page.setContextId(sourcePage.getContextId());
         page.setPageLayoutCode(sourcePage.getPageLayout().getCode());
+        page.setProperties(sourcePage.getProperties());
         page.setName(sourcePage.getName());
         page.setRegions(sourcePage.getRegions());
         //Enforce consistent casing for page types

Reply via email to