You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by ja...@apache.org on 2011/11/15 14:16:26 UTC
svn commit: r1202169 - in /incubator/rave/trunk:
rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/
rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/
rave-components/rave-web/src/main/java/org/apach...
Author: jasha
Date: Tue Nov 15 13:16:25 2011
New Revision: 1202169
URL: http://svn.apache.org/viewvc?rev=1202169&view=rev
Log:
RAVE-355 finish initial portal preference page (page title suffix, number of items per page)
RAVE-140 make number of items per page (in the main portal, not the admin interface) configurable
Added:
incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/PortalPreferenceKeys.java
incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/PortalPreferenceFormValidator.java
incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/PortalPreferenceControllerTest.java
incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/PortalPreferenceFormValidatorTest.java
Modified:
incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetService.java
incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/WidgetStoreController.java
incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/PortalPreferenceController.java
incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/model/PortalPreferenceForm.java
incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/WidgetStoreControllerTest.java
incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/model/PortalPreferenceFormTest.java
incubator/rave/trunk/rave-portal-resources/src/main/resources/messages.properties
incubator/rave/trunk/rave-portal-resources/src/main/resources/messages_nl.properties
incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/preferencedetail.jsp
incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/preferences.jsp
Modified: incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetService.java?rev=1202169&r1=1202168&r2=1202169&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetService.java (original)
+++ incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetService.java Tue Nov 15 13:16:25 2011
@@ -27,8 +27,6 @@ import org.apache.rave.portal.model.util
import org.apache.rave.portal.model.util.WidgetStatistics;
import org.apache.rave.portal.repository.WidgetRepository;
import org.apache.rave.portal.service.WidgetService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -39,8 +37,6 @@ import java.util.Map;
@Service
public class DefaultWidgetService implements WidgetService {
- private static Logger logger = LoggerFactory.getLogger(DefaultWidgetService.class);
-
private final WidgetRepository widgetRepository;
@Autowired
Modified: incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/WidgetStoreController.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/WidgetStoreController.java?rev=1202169&r1=1202168&r2=1202169&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/WidgetStoreController.java (original)
+++ incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/WidgetStoreController.java Tue Nov 15 13:16:25 2011
@@ -19,12 +19,15 @@
package org.apache.rave.portal.web.controller;
+import org.apache.rave.portal.model.PortalPreference;
import org.apache.rave.portal.model.User;
import org.apache.rave.portal.model.Widget;
import org.apache.rave.portal.model.WidgetStatus;
+import org.apache.rave.portal.service.PortalPreferenceService;
import org.apache.rave.portal.service.UserService;
import org.apache.rave.portal.service.WidgetService;
import org.apache.rave.portal.web.util.ModelKeys;
+import org.apache.rave.portal.web.util.PortalPreferenceKeys;
import org.apache.rave.portal.web.util.ViewNames;
import org.apache.rave.portal.web.validator.NewWidgetValidator;
import org.springframework.beans.factory.annotation.Autowired;
@@ -49,12 +52,15 @@ public class WidgetStoreController {
private final UserService userService;
+ private final PortalPreferenceService preferenceService;
+
@Autowired
public WidgetStoreController(WidgetService widgetService, NewWidgetValidator validator,
- UserService userService) {
+ UserService userService, PortalPreferenceService preferenceService) {
this.widgetService = widgetService;
this.widgetValidator = validator;
this.userService = userService;
+ this.preferenceService = preferenceService;
}
/**
@@ -70,7 +76,7 @@ public class WidgetStoreController {
@RequestParam(required = false, defaultValue = "0") int offset) {
User user = userService.getAuthenticatedUser();
model.addAttribute(ModelKeys.WIDGETS,
- widgetService.getPublishedWidgets(offset, MAXIMUM_WIDGETS_PER_PAGE));
+ widgetService.getPublishedWidgets(offset, getPageSize()));
model.addAttribute(ModelKeys.REFERRING_PAGE_ID, referringPageId);
model.addAttribute(ModelKeys.WIDGETS_STATISTICS, widgetService.getAllWidgetStatistics(user.getEntityId()));
return ViewNames.STORE;
@@ -100,7 +106,7 @@ public class WidgetStoreController {
*
* @param model {@link Model} map
* @param referringPageId the source {@link org.apache.rave.portal.model.Page } ID
- * @param searchTerm free text searchTerm query
+ * @param searchTerm free text searchTerm query
* @param offset offset within the total amount of results (to enable paging)
* @return the view name of the main store page
*/
@@ -110,8 +116,7 @@ public class WidgetStoreController {
@RequestParam(required = false, defaultValue = "0") int offset) {
User user = userService.getAuthenticatedUser();
model.addAttribute(ModelKeys.WIDGETS,
- widgetService.getPublishedWidgetsByFreeTextSearch(searchTerm, offset,
- MAXIMUM_WIDGETS_PER_PAGE));
+ widgetService.getPublishedWidgetsByFreeTextSearch(searchTerm, offset, getPageSize()));
model.addAttribute(ModelKeys.REFERRING_PAGE_ID, referringPageId);
model.addAttribute(ModelKeys.SEARCH_TERM, searchTerm);
model.addAttribute(ModelKeys.OFFSET, offset);
@@ -123,11 +128,12 @@ public class WidgetStoreController {
/**
* Shows the Add new Widget form
*
- * @param model {@link Model}
+ * @param model {@link Model}
+ * @param referringPageId the source {@link org.apache.rave.portal.model.Page } ID
* @return the view name of the Add new Widget form
*/
@RequestMapping(method = RequestMethod.GET, value = "widget/add")
- public String viewAddWidgetForm(Model model,@RequestParam long referringPageId) {
+ public String viewAddWidgetForm(Model model, @RequestParam long referringPageId) {
final Widget widget = new Widget();
model.addAttribute(ModelKeys.REFERRING_PAGE_ID, referringPageId);
model.addAttribute(ModelKeys.WIDGET, widget);
@@ -137,14 +143,15 @@ public class WidgetStoreController {
/**
* Validates the form input, if valid, tries to store the Widget data
*
- * @param widget {@link Widget} as submitted by the user
- * @param results {@link BindingResult}
- * @param model {@link Model}
+ * @param widget {@link Widget} as submitted by the user
+ * @param results {@link BindingResult}
+ * @param model {@link Model}
+ * @param referringPageId the source {@link org.apache.rave.portal.model.Page } ID
* @return if successful the view name of the widget, otherwise the form
*/
@RequestMapping(method = RequestMethod.POST, value = "widget/add")
public String viewAddWidgetResult(@ModelAttribute Widget widget, BindingResult results,
- Model model,@RequestParam long referringPageId ) {
+ Model model, @RequestParam long referringPageId) {
User user = userService.getAuthenticatedUser();
widgetValidator.validate(widget, results);
if (results.hasErrors()) {
@@ -157,8 +164,21 @@ public class WidgetStoreController {
final Widget storedWidget = widgetService.registerNewWidget(widget);
model.addAttribute(ModelKeys.REFERRING_PAGE_ID, referringPageId);
model.addAttribute(ModelKeys.WIDGET, storedWidget);
- model.addAttribute(ModelKeys.WIDGET_STATISTICS, widgetService.getWidgetStatistics(storedWidget.getEntityId(), user.getEntityId()));
+ model.addAttribute(ModelKeys.WIDGET_STATISTICS,
+ widgetService.getWidgetStatistics(storedWidget.getEntityId(), user.getEntityId()));
model.addAttribute(ModelKeys.USER_PROFILE, user);
return ViewNames.WIDGET;
}
+
+ public int getPageSize() {
+ final PortalPreference pageSizePref = preferenceService.getPreference(PortalPreferenceKeys.PAGE_SIZE);
+ if (pageSizePref == null) {
+ return MAXIMUM_WIDGETS_PER_PAGE;
+ }
+ try {
+ return Integer.parseInt(pageSizePref.getValue());
+ } catch (NumberFormatException e) {
+ return MAXIMUM_WIDGETS_PER_PAGE;
+ }
+ }
}
Modified: incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/PortalPreferenceController.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/PortalPreferenceController.java?rev=1202169&r1=1202168&r2=1202169&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/PortalPreferenceController.java (original)
+++ incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/PortalPreferenceController.java Tue Nov 15 13:16:25 2011
@@ -24,6 +24,7 @@ import org.apache.rave.portal.service.Po
import org.apache.rave.portal.web.model.PortalPreferenceForm;
import org.apache.rave.portal.web.util.ModelKeys;
import org.apache.rave.portal.web.util.ViewNames;
+import org.apache.rave.portal.web.validator.PortalPreferenceFormValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
@@ -37,13 +38,14 @@ import org.springframework.web.bind.anno
import org.springframework.web.bind.support.SessionStatus;
import java.util.Map;
+import java.util.Set;
+import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.addNavigationMenusToModel;
import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.checkTokens;
import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.isDeleteOrUpdate;
/**
* Controller for portal preferences
- * TODO RAVE-355 create unit tests
*/
@Controller
@SessionAttributes({"preferenceForm", ModelKeys.TOKENCHECK})
@@ -53,10 +55,13 @@ public class PortalPreferenceController
@Autowired
private PortalPreferenceService preferenceService;
+ @Autowired
+ private PortalPreferenceFormValidator formValidator;
+
@RequestMapping(value = {"/admin/preferences", "/admin/preferences/"}, method = RequestMethod.GET)
public String viewPreferences(@RequestParam(required = false) final String action, Model model) {
- AdminControllerUtil.addNavigationMenusToModel(SELECTED_ITEM, model);
-
+ addNavigationMenusToModel(SELECTED_ITEM, model);
+
final Map<String, PortalPreference> preferenceMap = preferenceService.getPreferencesAsMap();
model.addAttribute("preferenceMap", preferenceMap);
@@ -70,7 +75,7 @@ public class PortalPreferenceController
@RequestMapping(value = "/admin/preferencedetail/edit", method = RequestMethod.GET)
public String editPreferences(Model model) {
- AdminControllerUtil.addNavigationMenusToModel(SELECTED_ITEM, model);
+ addNavigationMenusToModel(SELECTED_ITEM, model);
final Map<String, PortalPreference> preferenceMap = preferenceService.getPreferencesAsMap();
PortalPreferenceForm form = new PortalPreferenceForm(preferenceMap);
@@ -83,16 +88,33 @@ public class PortalPreferenceController
@RequestMapping(value = "/admin/preferencedetail/update", method = RequestMethod.POST)
public String updatePreferences(@ModelAttribute("preferenceForm") PortalPreferenceForm form, BindingResult result,
@ModelAttribute(ModelKeys.TOKENCHECK) String sessionToken,
- @RequestParam() String token,
+ @RequestParam String token,
ModelMap modelMap,
SessionStatus status) {
checkTokens(sessionToken, token, status);
- preferenceService.savePreference(form.getPageSize());
- preferenceService.savePreference(form.getTitleSuffix());
+
+ formValidator.validate(form, result);
+ if (result.hasErrors()) {
+ addNavigationMenusToModel(SELECTED_ITEM, (Model) modelMap);
+ return ViewNames.ADMIN_PREFERENCE_DETAIL;
+ }
+
+ final Set<Map.Entry<String, PortalPreference>> entries = form.getPreferenceMap().entrySet();
+
+ for (Map.Entry<String, PortalPreference> entry : entries) {
+ preferenceService.savePreference(entry.getValue());
+ }
modelMap.clear();
status.setComplete();
return "redirect:/app/admin/preferences?action=update";
}
+ void setFormValidator(PortalPreferenceFormValidator formValidator) {
+ this.formValidator = formValidator;
+ }
+
+ public void setPreferenceService(PortalPreferenceService preferenceService) {
+ this.preferenceService = preferenceService;
+ }
}
Modified: incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/model/PortalPreferenceForm.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/model/PortalPreferenceForm.java?rev=1202169&r1=1202168&r2=1202169&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/model/PortalPreferenceForm.java (original)
+++ incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/model/PortalPreferenceForm.java Tue Nov 15 13:16:25 2011
@@ -21,47 +21,51 @@ package org.apache.rave.portal.web.model
import org.apache.rave.portal.model.PortalPreference;
-import java.util.HashMap;
import java.util.Map;
+import static org.apache.rave.portal.web.util.PortalPreferenceKeys.PAGE_SIZE;
+import static org.apache.rave.portal.web.util.PortalPreferenceKeys.TITLE_SUFFIX;
+
/**
* Form object for portal preferences
*/
public class PortalPreferenceForm {
- public static final String KEY_PAGE_SIZE = "pageSize";
public static final String DEFAULT_PAGE_SIZE = "10";
-
- public static final String KEY_TITLE_SUFFIX = "titleSuffix";
- public static final String DEFAULT_TITLE_SUFFIX = "- Rave";
+ public static final String DEFAULT_TITLE_SUFFIX = "";
private Map<String, PortalPreference> preferenceMap;
-
- public PortalPreferenceForm() {
- // TODO RAVE-355 populate preferences if they don't exist in the db
- this(new HashMap<String, PortalPreference>());
- }
public PortalPreferenceForm(Map<String, PortalPreference> preferenceMap) {
super();
this.preferenceMap = preferenceMap;
+ populateMissingPreferences();
+ }
+
+ private void populateMissingPreferences() {
+ if (getPageSize() == null) {
+ preferenceMap.put(PAGE_SIZE, new PortalPreference(PAGE_SIZE, DEFAULT_PAGE_SIZE));
+ }
+ if (getTitleSuffix() == null) {
+ preferenceMap.put(TITLE_SUFFIX, new PortalPreference(TITLE_SUFFIX, DEFAULT_TITLE_SUFFIX));
+ }
}
public PortalPreference getPageSize() {
- return preferenceMap.get(KEY_PAGE_SIZE);
+ return preferenceMap.get(PAGE_SIZE);
}
public void setPageSize(PortalPreference pageSize) {
- preferenceMap.put(KEY_PAGE_SIZE, pageSize);
+ preferenceMap.put(PAGE_SIZE, pageSize);
}
public PortalPreference getTitleSuffix() {
- return preferenceMap.get(KEY_TITLE_SUFFIX);
+ return preferenceMap.get(TITLE_SUFFIX);
}
public void setTitleSuffix(PortalPreference titleSuffix) {
- preferenceMap.put(KEY_TITLE_SUFFIX, titleSuffix);
+ preferenceMap.put(TITLE_SUFFIX, titleSuffix);
}
public Map<String, PortalPreference> getPreferenceMap() {
Added: incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/PortalPreferenceKeys.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/PortalPreferenceKeys.java?rev=1202169&view=auto
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/PortalPreferenceKeys.java (added)
+++ incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/PortalPreferenceKeys.java Tue Nov 15 13:16:25 2011
@@ -0,0 +1,33 @@
+/*
+ * 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.util;
+
+/**
+ * Utility class for {@link org.apache.rave.portal.model.PortalPreference} keys
+ */
+public final class PortalPreferenceKeys {
+ private PortalPreferenceKeys() {
+
+ }
+
+ public static final String TITLE_SUFFIX = "titleSuffix";
+ public static final String PAGE_SIZE = "pageSize";
+
+}
Added: incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/PortalPreferenceFormValidator.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/PortalPreferenceFormValidator.java?rev=1202169&view=auto
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/PortalPreferenceFormValidator.java (added)
+++ incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/PortalPreferenceFormValidator.java Tue Nov 15 13:16:25 2011
@@ -0,0 +1,64 @@
+/*
+ * 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.validator;
+
+import org.apache.rave.portal.web.model.PortalPreferenceForm;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.Errors;
+import org.springframework.validation.ValidationUtils;
+import org.springframework.validation.Validator;
+
+/**
+ * Validates {@link PortalPreferenceForm}
+ */
+@Component
+public class PortalPreferenceFormValidator implements Validator {
+
+ @Override
+ public boolean supports(Class<?> clazz) {
+ return PortalPreferenceForm.class.isAssignableFrom(clazz);
+ }
+
+ @Override
+ public void validate(Object target, Errors errors) {
+ PortalPreferenceForm form = (PortalPreferenceForm) target;
+
+ validateRequiredFields(errors);
+ validatePageSize(form, errors);
+ }
+
+ private void validateRequiredFields(Errors errors) {
+ ValidationUtils.rejectIfEmptyOrWhitespace(errors, "pageSize.value", "form.field.error.required");
+ }
+
+ private void validatePageSize(PortalPreferenceForm form, Errors errors) {
+ if (form.getPageSize() != null) {
+ int pageSizeValue;
+ try {
+ pageSizeValue = Integer.parseInt(form.getPageSize().getValue());
+ } catch (NumberFormatException e) {
+ pageSizeValue = 0;
+ }
+ if (pageSizeValue <= 0) {
+ errors.rejectValue("pageSize.value", "admin.preferencedetail.pageSize.malformed");
+ }
+ }
+ }
+}
Modified: incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/WidgetStoreControllerTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/WidgetStoreControllerTest.java?rev=1202169&r1=1202168&r2=1202169&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/WidgetStoreControllerTest.java (original)
+++ incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/WidgetStoreControllerTest.java Tue Nov 15 13:16:25 2011
@@ -25,9 +25,11 @@ import org.apache.rave.portal.model.Widg
import org.apache.rave.portal.model.WidgetStatus;
import org.apache.rave.portal.model.util.SearchResult;
import org.apache.rave.portal.model.util.WidgetStatistics;
+import org.apache.rave.portal.service.PortalPreferenceService;
import org.apache.rave.portal.service.UserService;
import org.apache.rave.portal.service.WidgetService;
import org.apache.rave.portal.web.util.ModelKeys;
+import org.apache.rave.portal.web.util.PortalPreferenceKeys;
import org.apache.rave.portal.web.util.ViewNames;
import org.apache.rave.portal.web.validator.NewWidgetValidator;
import org.junit.Before;
@@ -81,11 +83,17 @@ public class WidgetStoreControllerTest {
allWidgetStatisticsMap.put(WIDGET_ID, widgetStatistics);
widgetService = createMock(WidgetService.class);
+
UserService userService = createMock(UserService.class);
expect(userService.getAuthenticatedUser()).andReturn(validUser);
replay(userService);
+
+ PortalPreferenceService preferenceService = createMock(PortalPreferenceService.class);
+ expect(preferenceService.getPreference(PortalPreferenceKeys.PAGE_SIZE)).andReturn(null);
+ replay(preferenceService);
+
NewWidgetValidator widgetValidator = new NewWidgetValidator(widgetService);
- controller = new WidgetStoreController(widgetService, widgetValidator, userService);
+ controller = new WidgetStoreController(widgetService, widgetValidator, userService, preferenceService);
}
@Test
Added: incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/PortalPreferenceControllerTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/PortalPreferenceControllerTest.java?rev=1202169&view=auto
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/PortalPreferenceControllerTest.java (added)
+++ incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/PortalPreferenceControllerTest.java Tue Nov 15 13:16:25 2011
@@ -0,0 +1,189 @@
+/*
+ * 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.admin;
+
+import org.apache.rave.portal.model.PortalPreference;
+import org.apache.rave.portal.service.PortalPreferenceService;
+import org.apache.rave.portal.web.model.PortalPreferenceForm;
+import org.apache.rave.portal.web.util.ModelKeys;
+import org.apache.rave.portal.web.util.PortalPreferenceKeys;
+import org.apache.rave.portal.web.util.ViewNames;
+import org.apache.rave.portal.web.validator.PortalPreferenceFormValidator;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.ui.ExtendedModelMap;
+import org.springframework.ui.Model;
+import org.springframework.ui.ModelMap;
+import org.springframework.validation.BeanPropertyBindingResult;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.support.SessionStatus;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * Test for {@link PortalPreferenceController}
+ */
+public class PortalPreferenceControllerTest {
+
+ private PortalPreferenceController controller;
+ private PortalPreferenceService service;
+ private String validToken;
+
+ @Before
+ public void setUp() {
+ controller = new PortalPreferenceController();
+ service = createMock(PortalPreferenceService.class);
+ controller.setPreferenceService(service);
+ controller.setFormValidator(new PortalPreferenceFormValidator());
+ validToken = AdminControllerUtil.generateSessionToken();
+ }
+
+ @Test
+ public void testViewPreferences() {
+ Model model = new ExtendedModelMap();
+ Map<String, PortalPreference> preferenceMap = new HashMap<String, PortalPreference>();
+
+ expect(service.getPreferencesAsMap()).andReturn(preferenceMap);
+ replay(service);
+
+ String view = controller.viewPreferences(null, model);
+
+ assertEquals(ViewNames.ADMIN_PREFERENCES, view);
+ assertEquals(preferenceMap, model.asMap().get("preferenceMap"));
+ assertFalse(model.containsAttribute("actionresult"));
+ assertTrue(model.containsAttribute("topnav"));
+ assertTrue(model.containsAttribute("tabs"));
+
+ verify(service);
+ }
+
+ @Test
+
+ public void testViewPreferences_afterUpdate() {
+ Model model = new ExtendedModelMap();
+ Map<String, PortalPreference> preferenceMap = new HashMap<String, PortalPreference>();
+
+ expect(service.getPreferencesAsMap()).andReturn(preferenceMap);
+ replay(service);
+
+ final String action = "update";
+ String view = controller.viewPreferences(action, model);
+
+ assertEquals(ViewNames.ADMIN_PREFERENCES, view);
+ assertEquals(preferenceMap, model.asMap().get("preferenceMap"));
+ assertEquals(action, model.asMap().get("actionresult"));
+ assertTrue(model.containsAttribute("topnav"));
+ assertTrue(model.containsAttribute("tabs"));
+
+ verify(service);
+ }
+
+ @Test
+ public void testEditPreferences() {
+ Model model = new ExtendedModelMap();
+
+ Map<String, PortalPreference> preferenceMap = new HashMap<String, PortalPreference>();
+
+ expect(service.getPreferencesAsMap()).andReturn(preferenceMap);
+ replay(service);
+ String view = controller.editPreferences(model);
+ assertEquals(ViewNames.ADMIN_PREFERENCE_DETAIL, view);
+
+ assertTrue(model.asMap().get("preferenceForm") instanceof PortalPreferenceForm);
+ assertTrue(model.containsAttribute(ModelKeys.TOKENCHECK));
+ assertTrue(model.containsAttribute("topnav"));
+ assertTrue(model.containsAttribute("tabs"));
+ }
+
+ @Test
+ public void testUpdatePreferences_valid() {
+ ModelMap model = new ExtendedModelMap();
+ PortalPreferenceForm form = new PortalPreferenceForm(new HashMap<String, PortalPreference>());
+ final BindingResult errors = new BeanPropertyBindingResult(form, "form");
+ SessionStatus sessionStatus = createMock(SessionStatus.class);
+
+ final Set<Map.Entry<String, PortalPreference>> entries = form.getPreferenceMap().entrySet();
+
+ for (Map.Entry<String, PortalPreference> entry : entries) {
+ service.savePreference(entry.getValue());
+ }
+ sessionStatus.setComplete();
+
+ expectLastCall();
+ replay(service, sessionStatus);
+ String view = controller.updatePreferences(form, errors, validToken, validToken, model, sessionStatus);
+
+ assertEquals("redirect:/app/admin/preferences?action=update", view);
+ assertTrue("Model has been cleared", model.isEmpty());
+
+ verify(service, sessionStatus);
+ }
+
+ @Test(expected = SecurityException.class)
+ public void testUpdatePreferences_invalidToken() {
+ ModelMap model = new ExtendedModelMap();
+ String invalidToken = AdminControllerUtil.generateSessionToken();
+ PortalPreferenceForm form = new PortalPreferenceForm(new HashMap<String, PortalPreference>());
+ final BindingResult errors = new BeanPropertyBindingResult(form, "form");
+ SessionStatus sessionStatus = createMock(SessionStatus.class);
+ sessionStatus.setComplete();
+
+ expectLastCall();
+ replay(service, sessionStatus);
+ controller.updatePreferences(form, errors, validToken, invalidToken, model, sessionStatus);
+
+ assertFalse("Should not end up here", true);
+ verify(service, sessionStatus);
+ }
+
+ @Test
+ public void testUpdatePreferences_invalidPageSizeValue() {
+ ModelMap model = new ExtendedModelMap();
+ HashMap<String, PortalPreference> preferenceMap = new HashMap<String, PortalPreference>();
+ PortalPreference pageSizePref = new PortalPreference(PortalPreferenceKeys.PAGE_SIZE, "invalid");
+ preferenceMap.put(PortalPreferenceKeys.PAGE_SIZE, pageSizePref);
+ PortalPreferenceForm form = new PortalPreferenceForm(preferenceMap);
+ final BindingResult errors = new BeanPropertyBindingResult(form, "form");
+ SessionStatus sessionStatus = createMock(SessionStatus.class);
+
+ replay(service, sessionStatus);
+ String view = controller.updatePreferences(form, errors, validToken, validToken, model, sessionStatus);
+
+ assertEquals(ViewNames.ADMIN_PREFERENCE_DETAIL, view);
+ assertTrue(errors.hasErrors());
+ assertTrue(model.containsAttribute("topnav"));
+ assertTrue(model.containsAttribute("tabs"));
+ assertFalse("Model has not been cleared", model.isEmpty());
+
+ verify(service, sessionStatus);
+ }
+
+}
Modified: incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/model/PortalPreferenceFormTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/model/PortalPreferenceFormTest.java?rev=1202169&r1=1202168&r2=1202169&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/model/PortalPreferenceFormTest.java (original)
+++ incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/model/PortalPreferenceFormTest.java Tue Nov 15 13:16:25 2011
@@ -27,10 +27,8 @@ import java.util.HashMap;
import java.util.Map;
import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-import static org.apache.rave.portal.web.model.PortalPreferenceForm.KEY_PAGE_SIZE;
-import static org.apache.rave.portal.web.model.PortalPreferenceForm.KEY_TITLE_SUFFIX;
+import static org.apache.rave.portal.web.util.PortalPreferenceKeys.PAGE_SIZE;
+import static org.apache.rave.portal.web.util.PortalPreferenceKeys.TITLE_SUFFIX;
/**
* Test for {@link PortalPreferenceForm}
@@ -40,24 +38,23 @@ public class PortalPreferenceFormTest {
@Before
public void setUp() throws Exception {
- PortalPreference titlePref = new PortalPreference(KEY_TITLE_SUFFIX, "Test portal");
- preferenceMap.put(KEY_TITLE_SUFFIX, titlePref);
- PortalPreference pageSizePref = new PortalPreference(KEY_PAGE_SIZE, "20");
- preferenceMap.put(KEY_PAGE_SIZE, pageSizePref);
+ PortalPreference titlePref = new PortalPreference(TITLE_SUFFIX, "Test portal");
+ preferenceMap.put(TITLE_SUFFIX, titlePref);
+ PortalPreference pageSizePref = new PortalPreference(PAGE_SIZE, "20");
+ preferenceMap.put(PAGE_SIZE, pageSizePref);
}
@Test
- public void testEmptyConstructor() throws Exception {
- PortalPreferenceForm form = new PortalPreferenceForm();
- assertNull(form.getPageSize());
- assertNull(form.getTitleSuffix());
- assertTrue(form.getPreferenceMap().isEmpty());
- }
-
- @Test
- public void testPopulatedForm() throws Exception {
+ public void testForm_populatedMap() throws Exception {
PortalPreferenceForm form = new PortalPreferenceForm(preferenceMap);
assertEquals("Test portal", form.getTitleSuffix().getValue());
assertEquals("20", form.getPageSize().getValue());
}
+
+ @Test
+ public void testForm_emptyMap() throws Exception {
+ PortalPreferenceForm form = new PortalPreferenceForm(new HashMap<String, PortalPreference>());
+ assertEquals(PortalPreferenceForm.DEFAULT_PAGE_SIZE, form.getPageSize().getValue());
+ assertEquals(PortalPreferenceForm.DEFAULT_TITLE_SUFFIX, form.getTitleSuffix().getValue());
+ }
}
Added: incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/PortalPreferenceFormValidatorTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/PortalPreferenceFormValidatorTest.java?rev=1202169&view=auto
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/PortalPreferenceFormValidatorTest.java (added)
+++ incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/PortalPreferenceFormValidatorTest.java Tue Nov 15 13:16:25 2011
@@ -0,0 +1,92 @@
+/*
+ * 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.validator;
+
+import org.apache.rave.portal.model.PortalPreference;
+import org.apache.rave.portal.web.model.PortalPreferenceForm;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.validation.BindException;
+import org.springframework.validation.Errors;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+import static org.apache.rave.portal.web.util.PortalPreferenceKeys.PAGE_SIZE;
+import static org.apache.rave.portal.web.util.PortalPreferenceKeys.TITLE_SUFFIX;
+
+/**
+Test for {@link {PortalPreferenceFormValidator}
+ */
+public class PortalPreferenceFormValidatorTest {
+ private PortalPreferenceFormValidator validator;
+
+ @Before
+ public void setUp() throws Exception {
+ validator = new PortalPreferenceFormValidator();
+ }
+
+ @Test
+ public void testSupports() throws Exception {
+ assertTrue(validator.supports(PortalPreferenceForm.class));
+ }
+
+ @Test
+ public void testValidate_Valid() throws Exception {
+ Map<String, PortalPreference> preferenceMap = new HashMap<String, PortalPreference>();
+ preferenceMap.put(TITLE_SUFFIX, new PortalPreference(TITLE_SUFFIX, "- Rave unit test"));
+ preferenceMap.put(PAGE_SIZE, new PortalPreference(PAGE_SIZE, "10"));
+ PortalPreferenceForm form = new PortalPreferenceForm(preferenceMap);
+ Errors errors = new BindException(form, "form");
+ validator.validate(form, errors);
+
+ assertFalse(errors.hasErrors());
+ }
+
+
+ @Test
+ public void testValidate_missingRequiredFields() throws Exception {
+ Map<String, PortalPreference> preferenceMap = new HashMap<String, PortalPreference>();
+ PortalPreferenceForm form = new PortalPreferenceForm(preferenceMap);
+ form.getPageSize().setValue(null);
+ Errors errors = new BindException(form, "form");
+ validator.validate(form, errors);
+
+ assertEquals(2, errors.getErrorCount());
+ assertNotNull(errors.getFieldError("pageSize.value"));
+ }
+
+ @Test
+ public void testValidate_InvalidPageSize() throws Exception {
+ Map<String, PortalPreference> preferenceMap = new HashMap<String, PortalPreference>();
+ preferenceMap.put(PAGE_SIZE, new PortalPreference(PAGE_SIZE, "10.5"));
+ PortalPreferenceForm form = new PortalPreferenceForm(preferenceMap);
+ Errors errors = new BindException(form, "form");
+ validator.validate(form, errors);
+
+ assertEquals(1, errors.getErrorCount());
+ assertNotNull(errors.getFieldError("pageSize.value"));
+ }
+
+}
Modified: incubator/rave/trunk/rave-portal-resources/src/main/resources/messages.properties
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/main/resources/messages.properties?rev=1202169&r1=1202168&r2=1202169&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal-resources/src/main/resources/messages.properties (original)
+++ incubator/rave/trunk/rave-portal-resources/src/main/resources/messages.properties Tue Nov 15 13:16:25 2011
@@ -35,6 +35,7 @@ email.exists=This email address already
form.some.fields.required=Field marked with * are required
form.all.fields.required=All fields are required.
+form.field.error.required=This field is required
page.error.title=Rave has suffered a brief meltdown
page.error.message=Please bear with us while we fetch some ice cubes. In the meantime please try
@@ -153,8 +154,10 @@ admin.widgetdetail.action.delete.success
admin.widgetdetail.action.update.success=The widget has been updated
admin.preferences.title=Rave admin interface - Preferences
admin.preferences.shorttitle=Preferences
+admin.preferences.edit=Edit preferences
admin.preferencedetail.titleSuffix=Page title suffix
admin.preferencedetail.pageSize=Number of items per page (list)
+admin.preferencedetail.pageSize.malformed=Enter a whole number greater than 0
admin.preferencedetail.updateButton=Update preferences
admin.preferencedetail.action.update.success=Preferences have been updated
admin.preferencedetail.goback=\u00AB Back to overview
Modified: incubator/rave/trunk/rave-portal-resources/src/main/resources/messages_nl.properties
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/main/resources/messages_nl.properties?rev=1202169&r1=1202168&r2=1202169&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal-resources/src/main/resources/messages_nl.properties (original)
+++ incubator/rave/trunk/rave-portal-resources/src/main/resources/messages_nl.properties Tue Nov 15 13:16:25 2011
@@ -35,6 +35,7 @@ email.exists=Dit email adres bestaat al
form.some.fields.required=Velden met een * zijn verplicht
form.all.fields.required=Alle velden zijn verplicht
+form.field.error.required=Dit veld is verplicht
page.error.title=Oeps, er is iets misgegaan
page.error.message=Kaboutertjes zullen proberen het probleem op te lossen. Ondertussen kun je proberen de pagina te
@@ -153,8 +154,10 @@ admin.widgetdetail.action.delete.success
admin.widgetdetail.action.update.success=De widget is bijgewerkt
admin.preferences.title=Rave admin interface - Voorkeuren
admin.preferences.shorttitle=Voorkeuren
+admin.preferences.edit=Pas voorkeuren aan
admin.preferencedetail.titleSuffix=Toevoeging pagina titel
admin.preferencedetail.pageSize=Aantal items per pagina (lijst)
+admin.preferencedetail.pageSize.malformed=Voer een geheel getal in groter dan 0
admin.preferencedetail.updateButton=Wijzig voorkeuren
admin.preferencedetail.action.update.success=De voorkeuren zijn bijgewerkt
admin.preferencedetail.goback=\u00AB Terug naar overzicht
Modified: incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/preferencedetail.jsp
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/preferencedetail.jsp?rev=1202169&r1=1202168&r2=1202169&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/preferencedetail.jsp (original)
+++ incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/preferencedetail.jsp Tue Nov 15 13:16:25 2011
@@ -41,6 +41,7 @@
<form:errors cssClass="error" element="p"/>
<fieldset>
<input type="hidden" name="token" value="<c:out value="${tokencheck}"/>"/>
+ <p><fmt:message key="form.some.fields.required"/></p>
<p>
<form:label path="titleSuffix.value"><fmt:message key="admin.preferencedetail.titleSuffix"/></form:label>
@@ -51,7 +52,7 @@
<fieldset>
<p>
<spring:bind path="pageSize.value">
- <label for="pageSize"><fmt:message key="admin.preferencedetail.pageSize"/></label>
+ <label for="pageSize"><fmt:message key="admin.preferencedetail.pageSize"/> *</label>
<input id="pageSize" name="pageSize.value" type="number" step="1"
value="<c:out value="${status.value}"/>"/>
</spring:bind>
Modified: incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/preferences.jsp
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/preferences.jsp?rev=1202169&r1=1202168&r2=1202169&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/preferences.jsp (original)
+++ incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/preferences.jsp Tue Nov 15 13:16:25 2011
@@ -27,6 +27,7 @@
<rave:admin_tabsheader/>
<div class="pageContent">
<article class="admincontent">
+ <%--@elvariable id="actionresult" type="java.lang.String"--%>
<c:if test="${actionresult eq 'delete' or actionresult eq 'update'}">
<div class="alert-message success">
<p>
@@ -37,28 +38,37 @@
<h2><fmt:message key="admin.preferences.shorttitle"/></h2>
- <table class="datatable preferencestable">
- <tbody>
- <spring:url value="/app/admin/preferencedetail/edit" var="detaillink"/>
- <%--@elvariable id="preferenceMap" type="java.util.Map<java.lang.String, org.apache.rave.portal.model.PortalPreference>"--%>
- <c:forEach items="${preferenceMap}" var="entry">
- <c:set value="${entry.value}" var="portalPreference"/>
- <tr data-detaillink="${detaillink}">
- <th scope="row" class="largetextcell">
- <a href="${detaillink}"><fmt:message
- key="admin.preferencedetail.${portalPreference.key}"/></a>
- </th>
- <td class="largetextcell">
- <ul>
- <c:forEach items="${portalPreference.values}" var="value">
- <li><a href="${detaillink}"><c:out value="${value}"/></a></li>
- </c:forEach>
- </ul>
- </td>
- </tr>
- </c:forEach>
- </tbody>
- </table>
+ <spring:url value="/app/admin/preferencedetail/edit" var="detaillink"/>
+
+ <%--@elvariable id="preferenceMap" type="java.util.Map<java.lang.String, org.apache.rave.portal.model.PortalPreference>"--%>
+ <c:choose>
+ <c:when test="${fn:length(preferenceMap) eq 0}">
+ <a href="<c:out value="${detaillink}"/>"><fmt:message key="admin.preferences.edit"/></a>
+ </c:when>
+ <c:otherwise>
+ <table class="datatable preferencestable">
+ <tbody>
+ <c:forEach items="${preferenceMap}" var="entry">
+ <c:set value="${entry.value}" var="portalPreference"/>
+ <tr data-detaillink="<c:out value="${detaillink}"/>">
+ <th scope="row" class="largetextcell">
+ <a href="<c:out value="${detaillink}"/>"><fmt:message
+ key="admin.preferencedetail.${portalPreference.key}"/></a>
+ </th>
+ <td class="largetextcell">
+ <ul>
+ <c:forEach items="${portalPreference.values}" var="value">
+ <li><a href="<c:out value="${detaillink}"/>"><c:out value="${value}"/></a></li>
+ </c:forEach>
+ </ul>
+ </td>
+ </tr>
+ </c:forEach>
+ </tbody>
+ </table>
+ </c:otherwise>
+ </c:choose>
+
</article>
</div>
</rave:rave_generic_page>
\ No newline at end of file