Commit d57b4050 authored by Tobias Jeger's avatar Tobias Jeger

ESSENTIALS-719: Reintegrate fix to serialize Pagination into trunk.

parents cd7ab222 e36b1433
......@@ -71,6 +71,7 @@ components/hst/src/main/java/org/onehippo/cms7/essentials/components/paging/Defa
components/hst/src/main/java/org/onehippo/cms7/essentials/components/paging/IterablePagination.java -text
components/hst/src/main/java/org/onehippo/cms7/essentials/components/paging/Pageable.java -text
components/hst/src/main/java/org/onehippo/cms7/essentials/components/rest/BaseRestResource.java -text
components/hst/src/main/java/org/onehippo/cms7/essentials/components/rest/JaxbContextProvider.java -text
components/hst/src/main/java/org/onehippo/cms7/essentials/components/rest/adapters/HippoGalleryImageAdapter.java -text
components/hst/src/main/java/org/onehippo/cms7/essentials/components/rest/adapters/HippoHtmlAdapter.java -text
components/hst/src/main/java/org/onehippo/cms7/essentials/components/rest/adapters/RestLink.java -text
......@@ -81,6 +82,11 @@ components/hst/src/main/java/org/onehippo/cms7/essentials/components/utils/Compo
components/hst/src/main/java/org/onehippo/cms7/essentials/components/utils/SiteUtils.java -text
components/hst/src/main/java/org/onehippo/cms7/essentials/components/utils/query/HstQueryBuilder.java -text
components/hst/src/main/java/org/onehippo/cms7/essentials/components/utils/query/QueryBuilder.java -text
components/hst/src/test/java/org/onehippo/cms7/essentials/components/paging/DefaultPaginationTest.java -text
components/hst/src/test/java/org/onehippo/cms7/essentials/components/paging/IterablePaginationTest.java -text
components/hst/src/test/java/org/onehippo/cms7/essentials/components/paging/TestBean.java -text
components/hst/src/test/java/org/onehippo/cms7/essentials/components/rest/JaxbContextProviderTest.java -text
components/hst/src/test/resources/log4j.xml -text
components/pom.xml -text
dashboard-dependencies/pom.xml -text
dashboard/.bowerrc -text
......
......@@ -66,6 +66,11 @@
<version>${guava.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
......
......@@ -22,7 +22,8 @@ import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.hippoecm.hst.content.beans.standard.HippoBean;
......@@ -32,6 +33,7 @@ import org.hippoecm.hst.content.beans.standard.HippoBean;
* @version $Id$
*/
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement
public class DefaultPagination<T extends HippoBean> extends Pageable<T> {
......@@ -40,6 +42,10 @@ public class DefaultPagination<T extends HippoBean> extends Pageable<T> {
@SuppressWarnings({"RawUseOfParameterizedType", "rawtypes", "StaticVariableOfConcreteClass"})
private static final Pageable EMPTY_IMMUTABLE = new DefaultPagination(0, true);
public DefaultPagination() {
items = new ArrayList<>();
}
/**
* Returns empty immutable collection
*
......@@ -48,7 +54,7 @@ public class DefaultPagination<T extends HippoBean> extends Pageable<T> {
*/
@SuppressWarnings({"unchecked"})
public static <T extends HippoBean> DefaultPagination<T> emptyCollection() {
return (DefaultPagination<T>) EMPTY_IMMUTABLE;
return (DefaultPagination<T>)EMPTY_IMMUTABLE;
}
private DefaultPagination(final int total, final boolean empty) {
......@@ -77,7 +83,7 @@ public class DefaultPagination<T extends HippoBean> extends Pageable<T> {
items.add(item);
}
@XmlElement
@XmlAnyElement(lax = true)
@Override
public List<T> getItems() {
return items;
......
......@@ -19,7 +19,8 @@ package org.onehippo.cms7.essentials.components.paging;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.hippoecm.hst.content.beans.standard.HippoBean;
import org.hippoecm.hst.content.beans.standard.HippoBeanIterator;
......@@ -32,14 +33,18 @@ import org.slf4j.LoggerFactory;
*
* @version $Id$
*/
@XmlRootElement
public class IterablePagination<T extends HippoBean> extends Pageable<T> {
public static final String UNCHECKED = "unchecked";
private static Logger log = LoggerFactory.getLogger(IterablePagination.class);
private List<T> items;
public IterablePagination() {
items = new ArrayList<>();
}
/**
* Constructor to be used when the paging has been done beforehand (for example in HST query).
* The beans iterator size should be the same as pageSize (except maybe for the last page).
......@@ -127,15 +132,15 @@ public class IterablePagination<T extends HippoBean> extends Pageable<T> {
*
* @return all paged items
*/
@XmlElement
@XmlAnyElement(lax = true)
@Override
public List<? extends HippoBean> getItems() {
public List<T> getItems() {
return items;
}
@SuppressWarnings({UNCHECKED})
public void setItems(List<? extends HippoBean> items) {
this.items = (List<T>) items;
public void setItems(List<T> items) {
this.items = items;
}
......
......@@ -24,15 +24,13 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import org.hippoecm.hst.content.beans.standard.HippoBean;
/**
* Pageable
*
* @version $Id$
*/
@XmlAccessorType(XmlAccessType.NONE)
public abstract class Pageable<T extends HippoBean> {
public abstract class Pageable<T> {
private static final int DEFAULT_PAGE_RANGE = 10;
......@@ -54,6 +52,9 @@ public abstract class Pageable<T extends HippoBean> {
private boolean showPagination = true;
public Pageable() {
}
/**
* Constructor. NOTE: you can always override <code><strong>setTotal()</strong></code> method in your own class if
* total number of items is not available immediately
......@@ -182,7 +183,7 @@ public abstract class Pageable<T extends HippoBean> {
public List<Long> getPageNumbersArray() {
long startPage = getStartPage();
long endPage = getEndPage();
List<Long> pages = new ArrayList<Long>();
List<Long> pages = new ArrayList<>();
for (long i = startPage; i <= endPage; i++) {
pages.add(i);
}
......@@ -394,5 +395,5 @@ public abstract class Pageable<T extends HippoBean> {
@XmlElement
public abstract List<? extends HippoBean> getItems();
public abstract List<T> getItems();
}
......@@ -157,7 +157,7 @@ public abstract class BaseRestResource extends AbstractResource {
final HstQueryResult results = query.execute();
final HippoBeanIterator beans = results.getHippoBeans();
if (beans.hasNext()) {
return (T) beans.nextHippoBean();
return (T)beans.nextHippoBean();
}
return null;
......@@ -169,7 +169,7 @@ public abstract class BaseRestResource extends AbstractResource {
List<T> retval = new ArrayList<>();
if (beans.hasNext()) {
@SuppressWarnings({UNCHECKED})
final T bean = (T) beans.nextHippoBean();
final T bean = (T)beans.nextHippoBean();
if (bean != null) {
retval.add(bean);
}
......
/*
* Copyright 2015 Hippo B.V. (http://www.onehippo.com)
*
* Licensed 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.onehippo.cms7.essentials.components.rest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlRootElement;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.ClassPath;
import org.onehippo.cms7.essentials.components.paging.DefaultPagination;
import org.onehippo.cms7.essentials.components.paging.IterablePagination;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
@Provider
public class JaxbContextProvider implements ContextResolver<JAXBContext> {
private static final Logger log = LoggerFactory.getLogger(JaxbContextProvider.class);
private JAXBContext context;
private String beansPackage;
private List<Class<?>> classes;
public JaxbContextProvider() throws Exception {
log.debug("Creating custom JAXB ContextResolver");
}
@Override
public JAXBContext getContext(Class<?> objectType) {
if (context == null) {
try {
final List<Class<?>> allClasses = new ArrayList<>();
includeAnnotatedTopLevelClassesFromBeansPackage(allClasses);
if (classes != null) {
allClasses.addAll(classes);
}
// Hard-coded classes to include
allClasses.add(IterablePagination.class);
allClasses.add(DefaultPagination.class);
context = JAXBContext.newInstance(allClasses.toArray(new Class[allClasses.size()]));
} catch (JAXBException | IOException | ClassNotFoundException e) {
log.error("Error creating JAXB context:", e);
}
}
return context;
}
private void includeAnnotatedTopLevelClassesFromBeansPackage(final List<Class<?>> allClasses)
throws IOException, ClassNotFoundException {
if (!Strings.isNullOrEmpty(beansPackage)) {
final ClassPath classPath = ClassPath.from(getClass().getClassLoader());
final ImmutableSet<ClassPath.ClassInfo> topLevelClasses = classPath.getTopLevelClassesRecursive(beansPackage);
for (ClassPath.ClassInfo topLevelClass : topLevelClasses) {
final String name = topLevelClass.getName();
final Class<?> clazz = Class.forName(name);
if (clazz.isAnnotationPresent(XmlRootElement.class)) {
allClasses.add(clazz);
}
}
}
}
public List<Class<?>> getClasses() {
return classes;
}
public void setClasses(final List<Class<?>> classes) {
this.classes = classes;
}
public void setBeansPackage(String beansPackage) {
this.beansPackage = beansPackage;
}
public String getBeansPackage() {
return beansPackage;
}
}
/*
* Copyright 2015 Hippo B.V. (http://www.onehippo.com)
*
* Licensed 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.onehippo.cms7.essentials.components.paging;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertTrue;
public class DefaultPaginationTest {
private static final Logger log = LoggerFactory.getLogger(DefaultPaginationTest.class);
@Test
public void testJaxb() throws Exception {
final List<TestBean> testBeans = new ArrayList<>();
final TestBean testBean = new TestBean();
testBeans.add(testBean);
final DefaultPagination<TestBean> value = new DefaultPagination<>(testBeans);
final JAXBContext context = JAXBContext.newInstance(DefaultPagination.class, TestBean.class);
final Marshaller m = context.createMarshaller();
final Unmarshaller unmarshaller = context.createUnmarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
final StringWriter writer = new StringWriter();
m.marshal(value, writer);
final String xml = writer.toString();
log.info("writer {}", xml);
@SuppressWarnings("unchecked")
final DefaultPagination<TestBean> v = (DefaultPagination<TestBean>)unmarshaller.unmarshal(new StringReader(xml));
assertTrue(v.getItems().size() == 1);
assertTrue(v.getItems().get(0).getTitle().equals(testBean.getTitle()));
}
}
\ No newline at end of file
/*
* Copyright 2015 Hippo B.V. (http://www.onehippo.com)
*
* Licensed 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.onehippo.cms7.essentials.components.paging;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertTrue;
public class IterablePaginationTest {
private static final Logger log = LoggerFactory.getLogger(IterablePaginationTest.class);
@Test
public void testJaxb() throws Exception {
final List<TestBean> testBeans = new ArrayList<>();
final TestBean testBean = new TestBean();
testBeans.add(testBean);
final IterablePagination<TestBean> value = new IterablePagination<>(testBeans, 1, 1);
final JAXBContext context = JAXBContext.newInstance(IterablePagination.class, TestBean.class);
final Marshaller m = context.createMarshaller();
final Unmarshaller unmarshaller = context.createUnmarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
final StringWriter writer = new StringWriter();
m.marshal(value, writer);
final String xml = writer.toString();
log.info("writer {}", xml);
@SuppressWarnings("unchecked")
final IterablePagination<TestBean> v = (IterablePagination<TestBean>)unmarshaller.unmarshal(new StringReader(xml));
assertTrue(v.getItems().size() == 1);
assertTrue(v.getItems().get(0).getTitle().equals(testBean.getTitle()));
}
}
\ No newline at end of file
/*
* Copyright 2015 Hippo B.V. (http://www.onehippo.com)
*
* Licensed 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.onehippo.cms7.essentials.components.paging;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.hippoecm.hst.content.beans.standard.HippoItem;
@XmlRootElement(name = "TestBean")
@XmlAccessorType(XmlAccessType.NONE)
public class TestBean extends HippoItem {
@XmlElement
public String getTitle() {
return "testTitle";
}
}
/*
* Copyright 2015 Hippo B.V. (http://www.onehippo.com)
*
* Licensed 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.onehippo.cms7.essentials.components.rest;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.junit.Test;
import org.onehippo.cms7.essentials.components.paging.DefaultPagination;
import org.onehippo.cms7.essentials.components.paging.TestBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertTrue;
public class JaxbContextProviderTest {
private static final Logger log = LoggerFactory.getLogger(JaxbContextProviderTest.class);
@Test
public void testGetClasses() throws Exception {
final List<TestBean> testBeans = new ArrayList<>();
final TestBean testBean = new TestBean();
testBeans.add(testBean);
final DefaultPagination<TestBean> value = new DefaultPagination<>(testBeans);
final JaxbContextProvider provider = new JaxbContextProvider();
provider.setBeansPackage(TestBean.class.getPackage().getName());
final JAXBContext context = provider.getContext(Object.class);
final Marshaller m = context.createMarshaller();
final Unmarshaller unmarshaller = context.createUnmarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
final StringWriter writer = new StringWriter();
m.marshal(value, writer);
final String xml = writer.toString();
log.info("writer {}", xml);
@SuppressWarnings("unchecked")
final DefaultPagination<TestBean> v = (DefaultPagination<TestBean>)unmarshaller.unmarshal(new StringReader(xml));
assertTrue(v.getItems().size() == 1);
assertTrue(v.getItems().get(0).getTitle().equals(testBean.getTitle()));
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright 2015 Hippo B.V. (http://www.onehippo.com)
Licensed 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.
-->
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- ====================================================================== -->
<!-- A P P E N D E R S -->
<!-- ====================================================================== -->
<!-- console -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p - [%-80m] - at %c.%M(%F:%L)%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="levelMin" value="DEBUG"/>
</filter>
</appender>
<!-- ====================================================================== -->
<!-- L O G G E R S -->
<!-- ====================================================================== -->
<!-- CMS logging -->
<logger name="org.apache.jackrabbit.core">
<level value="warn"/>
</logger>
<logger name="org.apache.jackrabbit.extractor">
<level value="warn"/>
</logger>
<logger name="org.apache.jackrabbit">
<level value="warn"/>
</logger>
<logger name="org.hippoecm.repository">
<level value="warn"/>
</logger>
<logger name="org.hippoecm.frontend">
<level value="warn"/>
</logger>
<logger name="org.apache.wicket">
<level value="warn"/>
</logger>
<!-- audit logging -->
<logger additivity="false" name="org.hippoecm.repository.api.Workflow">
<level value="info"/>
</logger>
<logger additivity="false" name="org.onehippo.audit">
<level value="info"/>
</logger>
<!-- Site logging -->
<logger name="org.hippoecm.hst">
<level value="warn"/>
</logger>
<!-- DiagnosticReportingValve only logs when diagnostics enabled in hst:hosts config in repo hence
can be here on level 'info' -->
<logger name="org.hippoecm.hst.core.container.DiagnosticReportingValve">
<level value="info"/>
</logger>
<logger name="freemarker">
<level value="warn"/>
</logger>
<logger name="org.apache.cxf">
<level value="warn"/>
</logger>
<logger name="javax.ws.rs.core">
<level value="warn"/>
</logger>
<logger name="org.apache.commons.pool">
<level value="warn"/>
</logger>
<logger name="org.apache.commons.beanutils">
<level value="warn"/>
</logger>
<!-- too many caching warnings -->
<logger name="org.apache.jackrabbit.core.state">
<level value="error"/>
</logger>
<logger name="org.apache.jackrabbit.core.ItemManager">
<level value="error"/>
</logger>
<logger name="org.apache.jackrabbit.core.persistence.bundle.util.LRUNodeIdCache">
<level value="error"/>
</logger>
<!-- ignore wicket localizer warnings -->
<logger name="org.apache.wicket.Localizer">
<level value="error"/>
</logger>
<!-- ignore DataNucleus errors -->
<logger name="DataNucleus.Plugin">
<level value="fatal"/>
</logger>
<logger name="DataNucleus.ClassLoading">
<level value="fatal"/>
</logger>
<logger name="DataNucleus.Enhancer">
<level value="fatal"/>
</logger>
<!-- more info wanted -->
<logger name="org.apache.jackrabbit.core.persistence.bundle">
<level value="warn"/>
</logger>
<logger name="org.hippoecm.repository.jackrabbit.persistence">
<level value="info"/>
</logger>
<logger name="org.hippoecm.repository.updater">
<level value="info"/>
</logger>
<logger name="org.onehippo.cms7.autoexport">
<level value="info"/>
</logger>
<logger name="org.springframework">
<level value="warn"/>
</logger>
<logger name="org.onehippo.cms7.essentials">
<level value="debug"/>
</logger>
<root>
<level value="info"/>
<appender-ref ref="console"/>
</root>
</log4j:configuration>
......@@ -17,8 +17,8 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="classpath:/org/hippoecm/hst/site/optional/jaxrs/SpringComponentManager-rest-jackson.xml"/>
<import resource="classpath:/org/hippoecm/hst/site/optional/jaxrs/SpringComponentManager-rest-plain-pipeline.xml"/>
......@@ -37,6 +37,56 @@
</list>
</property>
</bean>
<!--