Return-Path: X-Original-To: apmail-incubator-rave-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-rave-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 2921D9CB6 for ; Wed, 7 Mar 2012 17:10:08 +0000 (UTC) Received: (qmail 75977 invoked by uid 500); 7 Mar 2012 17:10:08 -0000 Delivered-To: apmail-incubator-rave-commits-archive@incubator.apache.org Received: (qmail 75908 invoked by uid 500); 7 Mar 2012 17:10:07 -0000 Mailing-List: contact rave-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: rave-dev@incubator.apache.org Delivered-To: mailing list rave-commits@incubator.apache.org Received: (qmail 75884 invoked by uid 99); 7 Mar 2012 17:10:06 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 07 Mar 2012 17:10:06 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 07 Mar 2012 17:09:58 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id EE2402388CA9; Wed, 7 Mar 2012 17:09:35 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1298022 - in /incubator/rave/trunk: rave-components/rave-commons/ rave-components/rave-commons/src/main/java/org/apache/rave/model/ rave-components/rave-commons/src/main/java/org/apache/rave/service/ rave-components/rave-commons/src/main/j... Date: Wed, 07 Mar 2012 17:09:35 -0000 To: rave-commits@incubator.apache.org From: carlucci@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120307170935.EE2402388CA9@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: carlucci Date: Wed Mar 7 17:09:34 2012 New Revision: 1298022 URL: http://svn.apache.org/viewvc?rev=1298022&view=rev Log: RAVE-506: Static Content Fetcher Added: incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/model/ incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/model/StaticContent.java incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/service/StaticContentFetcherService.java incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/service/impl/DefaultStaticContentFetcherService.java incubator/rave/trunk/rave-components/rave-commons/src/test/java/org/apache/rave/service/impl/DefaultStaticContentFetcherServiceTest.java incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/tag/StaticContentTag.java - copied, changed from r1297542, incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/tag/RegionWidgetTag.java incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/tag/StaticContentTagTest.java Modified: incubator/rave/trunk/rave-components/rave-commons/pom.xml incubator/rave/trunk/rave-components/rave-core/src/main/resources/org/apache/rave/core-applicationContext.xml incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/interceptors/CommonModelHandlerInterceptor.java incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/ModelKeys.java incubator/rave/trunk/rave-components/rave-web/src/main/resources/META-INF/rave.tld incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/interceptors/CommonModelHandlerInterceptorTest.java incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/common/header.jsp Modified: incubator/rave/trunk/rave-components/rave-commons/pom.xml URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-commons/pom.xml?rev=1298022&r1=1298021&r2=1298022&view=diff ============================================================================== --- incubator/rave/trunk/rave-components/rave-commons/pom.xml (original) +++ incubator/rave/trunk/rave-components/rave-commons/pom.xml Wed Mar 7 17:09:34 2012 @@ -61,6 +61,10 @@ org.springframework + spring-web + + + org.springframework spring-orm @@ -106,6 +110,11 @@ aspectjweaver 1.6.9 + + org.springframework + spring-test + test + \ No newline at end of file Added: incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/model/StaticContent.java URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/model/StaticContent.java?rev=1298022&view=auto ============================================================================== --- incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/model/StaticContent.java (added) +++ incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/model/StaticContent.java Wed Mar 7 17:09:34 2012 @@ -0,0 +1,68 @@ +/* + * 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.model; + + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +/** + * POJO representing a static content artifact + */ +public class StaticContent { + private String id; + private URI location; + private String content; + // replacementTokens can be used when the static content artifact is a template and needs some + // environment specific tokens to be replaced + private Map replacementTokens; + + public StaticContent(String id, URI location, Map replacementTokens) { + this.id = id; + this.location = location; + this.replacementTokens = replacementTokens == null ? new HashMap() : replacementTokens; + this.content = ""; + } + + public String getId() { + return id; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public URI getLocation() { + return location; + } + + public Map getReplacementTokens() { + return replacementTokens; + } + + @Override + public String toString() { + return "StaticContent{" + "id=" + id + ", location=" + location + "}"; + } +} Added: incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/service/StaticContentFetcherService.java URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/service/StaticContentFetcherService.java?rev=1298022&view=auto ============================================================================== --- incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/service/StaticContentFetcherService.java (added) +++ incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/service/StaticContentFetcherService.java Wed Mar 7 17:09:34 2012 @@ -0,0 +1,44 @@ +/* + * 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.service; + +/** + * Interface for dealing with remote Static Content (such as HTML or JavaScript fragments) so that + * Rave can render them directly on pages and improve performance by internally caching the content + */ +public interface StaticContentFetcherService { + /** + * Returns the content from the cache for the supplied key + * + * @param key the cache key of the content artifact to lookup + * @return String representing the static content + */ + String getContent(String key); + + /** + * Refreshes all of the cached StaticContent artifacts currently in the cache + */ + void refreshAll(); + + /** + * Refresh a single StaticContent artifact in the cache based on the supplied key + * @param key the cache key of the content artifact to refresh + */ + void refresh(String key); +} Added: incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/service/impl/DefaultStaticContentFetcherService.java URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/service/impl/DefaultStaticContentFetcherService.java?rev=1298022&view=auto ============================================================================== --- incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/service/impl/DefaultStaticContentFetcherService.java (added) +++ incubator/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/service/impl/DefaultStaticContentFetcherService.java Wed Mar 7 17:09:34 2012 @@ -0,0 +1,89 @@ +/* + * 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.service.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.rave.model.StaticContent; +import org.apache.rave.service.StaticContentFetcherService; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class DefaultStaticContentFetcherService implements StaticContentFetcherService { + private static final Log log = LogFactory.getLog(DefaultStaticContentFetcherService.class); + private Map contentMap; + private RestTemplate restTemplate; + + public DefaultStaticContentFetcherService(RestTemplate restTemplate, List contentObjects) { + this.restTemplate = restTemplate; + contentMap = new HashMap(); + for (StaticContent contentObject : contentObjects) { + contentMap.put(contentObject.getId(), contentObject); + } + } + + @Override + public String getContent(String key) { + log.debug("getContent(" + key + ")"); + StaticContent content = contentMap.get(key); + if (content == null) { + throw new IllegalArgumentException("Invalid content key: " + key); + } + return content.getContent(); + } + + @Override + public void refreshAll() { + log.debug("refreshAll()"); + for (StaticContent curEntry : contentMap.values()) { + refreshFromLocation(curEntry); + } + } + + @Override + public void refresh(String key) { + log.debug("refresh(" + key + ")"); + //if the key exists in the content map, refresh it + StaticContent item = contentMap.get(key); + if (item != null) { + refreshFromLocation(item); + } + } + + private void refreshFromLocation(StaticContent staticContent) { + log.debug("refreshFromLocation() - for " + staticContent); + try { + //We need an intermediate temp content string here so we don't even accidentally hand out a reference to + //a not-fully-token-replaced piece of content. Very unlikely, but could happen. + String tempContent = restTemplate.getForObject(staticContent.getLocation(), String.class); + for (Map.Entry replacementTokenEntry : staticContent.getReplacementTokens().entrySet()) { + tempContent = tempContent.replaceAll(replacementTokenEntry.getKey(), replacementTokenEntry.getValue()); + } + staticContent.setContent(tempContent); + } catch (RestClientException e) { + //RestClientException handles server errors 5xx, client errors 4xx, and IO errors + log.error("Unable to process {" + staticContent.getLocation() + "}", e); + } + } +} Added: incubator/rave/trunk/rave-components/rave-commons/src/test/java/org/apache/rave/service/impl/DefaultStaticContentFetcherServiceTest.java URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-commons/src/test/java/org/apache/rave/service/impl/DefaultStaticContentFetcherServiceTest.java?rev=1298022&view=auto ============================================================================== --- incubator/rave/trunk/rave-components/rave-commons/src/test/java/org/apache/rave/service/impl/DefaultStaticContentFetcherServiceTest.java (added) +++ incubator/rave/trunk/rave-components/rave-commons/src/test/java/org/apache/rave/service/impl/DefaultStaticContentFetcherServiceTest.java Wed Mar 7 17:09:34 2012 @@ -0,0 +1,212 @@ +/* + * 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.service.impl; + +import org.apache.rave.model.StaticContent; +import org.junit.Before; +import org.junit.Test; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import static org.easymock.EasyMock.*; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class DefaultStaticContentFetcherServiceTest { + private RestTemplate restTemplate; + + private final String VALID_URL1 = "http://www.google.com/"; + private final String VALID_URL1_ID = "google"; + private final String VALID_URL1_CONTENT = "Bogus www.google.page"; + private StaticContent VALID_CONTENT_1; + + private final String VALID_URL2 = "http://www.yahoo.com/"; + private final String VALID_URL2_ID = "yahoo"; + private final String VALID_URL2_CONTENT = "Bogus www.yahoo.page"; + private StaticContent VALID_CONTENT_2; + + private final String VALID_URL3 = "http://www.bing.com/"; + private final String VALID_URL3_ID = "bing"; + private final String VALID_URL3_CONTENT = "Bogus www.bing.page with replacement tokens: {token1} && {token2}"; + private final String VALID_URL3_TOKEN_1 = "\\{token1\\}"; + private final String VALID_URL3_TOKEN_2 = "\\{token2\\}"; + private final String VALID_URL3_TOKEN_1_REPLACEMENT = "token-1-value"; + private final String VALID_URL3_TOKEN_2_REPLACEMENT = "token-2-value"; + private final String VALID_URL3_CONTENT_WITH_REPLACEMENTS = VALID_URL3_CONTENT + .replaceAll(VALID_URL3_TOKEN_1, VALID_URL3_TOKEN_1_REPLACEMENT) + .replaceAll(VALID_URL3_TOKEN_2, VALID_URL3_TOKEN_2_REPLACEMENT); + private StaticContent VALID_CONTENT_3; + + @Before + public void setUp() throws URISyntaxException { + VALID_CONTENT_1 = new StaticContent(VALID_URL1_ID, new URI(VALID_URL1), null); + VALID_CONTENT_2 = new StaticContent(VALID_URL2_ID, new URI(VALID_URL2), null); + VALID_CONTENT_3 = new StaticContent(VALID_URL3_ID, new URI(VALID_URL3), null); + + restTemplate = createNiceMock(RestTemplate.class); + } + + @Test + public void getContent_validId() throws URISyntaxException { + DefaultStaticContentFetcherService service = new DefaultStaticContentFetcherService(restTemplate, Arrays.asList(VALID_CONTENT_1, VALID_CONTENT_2, VALID_CONTENT_3)); + expectAllRestTemplateGetForObject(); + replay(restTemplate); + + //Initially all content will be blank + assertBlankInitialContent(service); + + service.refreshAll(); + + //Now that the content has been refreshed we should get a valid value + assertThat(service.getContent(VALID_URL1_ID), is(VALID_URL1_CONTENT)); + + verify(restTemplate); + } + + @Test + public void getContent_validIdsWithReplacementTokens() throws URISyntaxException { + //Setup our third content object to use the replacement feature and test for it + Map tokenReplacements = new HashMap(); + tokenReplacements.put(VALID_URL3_TOKEN_1, VALID_URL3_TOKEN_1_REPLACEMENT); + tokenReplacements.put(VALID_URL3_TOKEN_2, VALID_URL3_TOKEN_2_REPLACEMENT); + VALID_CONTENT_3 = new StaticContent(VALID_URL3_ID, new URI(VALID_URL3), tokenReplacements); + + expectAllRestTemplateGetForObject(); + replay(restTemplate); + + DefaultStaticContentFetcherService service = new DefaultStaticContentFetcherService(restTemplate, Arrays.asList(VALID_CONTENT_1, VALID_CONTENT_2, VALID_CONTENT_3)); + + service.refreshAll(); + + assertThat(service.getContent(VALID_URL1_ID), is(VALID_URL1_CONTENT)); + assertThat(service.getContent(VALID_URL2_ID), is(VALID_URL2_CONTENT)); + assertThat(service.getContent(VALID_URL3_ID), is(VALID_URL3_CONTENT_WITH_REPLACEMENTS)); + + verify(restTemplate); + } + + @Test(expected = IllegalArgumentException.class) + public void getContent_invalidId() { + DefaultStaticContentFetcherService service = new DefaultStaticContentFetcherService(restTemplate, Arrays.asList(VALID_CONTENT_1, VALID_CONTENT_2, VALID_CONTENT_3)); + service.getContent("INVALID"); + } + + @Test + public void refreshAll() throws URISyntaxException { + DefaultStaticContentFetcherService service = new DefaultStaticContentFetcherService(restTemplate, Arrays.asList(VALID_CONTENT_1, VALID_CONTENT_2, VALID_CONTENT_3)); + + assertBlankInitialContent(service); + + expectAllRestTemplateGetForObject(); + replay(restTemplate); + + service.refreshAll(); + + //Now that the content has been refreshed we should get a valid value + assertThat(service.getContent(VALID_URL1_ID), is(VALID_URL1_CONTENT)); + assertThat(service.getContent(VALID_URL2_ID), is(VALID_URL2_CONTENT)); + assertThat(service.getContent(VALID_URL3_ID), is(VALID_URL3_CONTENT)); + } + + @Test + public void refresh_invalidKey() throws URISyntaxException { + DefaultStaticContentFetcherService service = new DefaultStaticContentFetcherService(restTemplate, Arrays.asList(VALID_CONTENT_1, VALID_CONTENT_2, VALID_CONTENT_3)); + + assertBlankInitialContent(service); + + expectAllRestTemplateGetForObject(); + replay(restTemplate); + + service.refresh("INVALID_CACHE_KEY"); + + //Now that the content has been refreshed we should get a valid value + assertThat(service.getContent(VALID_URL1_ID), is("")); + assertThat(service.getContent(VALID_URL2_ID), is("")); + assertThat(service.getContent(VALID_URL3_ID), is("")); + } + + @Test + public void refresh_validKey() throws URISyntaxException { + DefaultStaticContentFetcherService service = new DefaultStaticContentFetcherService(restTemplate, Arrays.asList(VALID_CONTENT_1, VALID_CONTENT_2, VALID_CONTENT_3)); + + assertBlankInitialContent(service); + + expectAllRestTemplateGetForObject(); + replay(restTemplate); + + service.refresh(VALID_URL2_ID); + + //Now that the content has been refreshed we should get a valid value + assertThat(service.getContent(VALID_URL1_ID), is("")); + assertThat(service.getContent(VALID_URL2_ID), is(VALID_URL2_CONTENT)); + assertThat(service.getContent(VALID_URL3_ID), is("")); + } + + @Test + public void refresh_fetchErrorExistingValidContentPreserved() throws URISyntaxException { + //Create the fetcher, refresh the content and then validate that we have the expected content + DefaultStaticContentFetcherService service = new DefaultStaticContentFetcherService(restTemplate, Arrays.asList(VALID_CONTENT_1, VALID_CONTENT_2, VALID_CONTENT_3)); + + expectAllRestTemplateGetForObject(); + replay(restTemplate); + + service.refreshAll(); + + assertThat(service.getContent(VALID_URL1_ID), is(VALID_URL1_CONTENT)); + assertThat(service.getContent(VALID_URL2_ID), is(VALID_URL2_CONTENT)); + assertThat(service.getContent(VALID_URL3_ID), is(VALID_URL3_CONTENT)); + + //Now create a new RestTemplate mock and have it return new content for two of the items and throw an exception + //for the third -- in this case the two items should have the new content but the third with the exception should + //retain the old good cached content. + String newContent = "new content from refresh"; + restTemplate = createNiceMock(RestTemplate.class); + expect(restTemplate.getForObject(new URI(VALID_URL1), String.class)).andReturn(newContent); + expect(restTemplate.getForObject(new URI(VALID_URL2), String.class)).andThrow(new RestClientException("Boom")); + expect(restTemplate.getForObject(new URI(VALID_URL3), String.class)).andReturn(newContent); + replay(restTemplate); + //Use reflection to stuff the new RestTemplate instance into our existing content fetcher instance + ReflectionTestUtils.setField(service, "restTemplate", restTemplate); + + service.refreshAll(); + + assertThat(service.getContent(VALID_URL1_ID), is(newContent)); + assertThat(service.getContent(VALID_URL2_ID), is(VALID_URL2_CONTENT)); + assertThat(service.getContent(VALID_URL3_ID), is(newContent)); + } + + private void expectAllRestTemplateGetForObject() throws URISyntaxException { + expect(restTemplate.getForObject(new URI(VALID_URL1), String.class)).andReturn(VALID_URL1_CONTENT); + expect(restTemplate.getForObject(new URI(VALID_URL2), String.class)).andReturn(VALID_URL2_CONTENT); + expect(restTemplate.getForObject(new URI(VALID_URL3), String.class)).andReturn(VALID_URL3_CONTENT); + } + + private void assertBlankInitialContent(DefaultStaticContentFetcherService service) { + assertThat(service.getContent(VALID_URL1_ID), is("")); + assertThat(service.getContent(VALID_URL2_ID), is("")); + assertThat(service.getContent(VALID_URL3_ID), is("")); + } +} Modified: incubator/rave/trunk/rave-components/rave-core/src/main/resources/org/apache/rave/core-applicationContext.xml URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/main/resources/org/apache/rave/core-applicationContext.xml?rev=1298022&r1=1298021&r2=1298022&view=diff ============================================================================== --- incubator/rave/trunk/rave-components/rave-core/src/main/resources/org/apache/rave/core-applicationContext.xml (original) +++ incubator/rave/trunk/rave-components/rave-core/src/main/resources/org/apache/rave/core-applicationContext.xml Wed Mar 7 17:09:34 2012 @@ -124,13 +124,13 @@ --> - + + + + + + + + + + + + + + \ No newline at end of file Modified: incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/interceptors/CommonModelHandlerInterceptor.java URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/interceptors/CommonModelHandlerInterceptor.java?rev=1298022&r1=1298021&r2=1298022&view=diff ============================================================================== --- incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/interceptors/CommonModelHandlerInterceptor.java (original) +++ incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/interceptors/CommonModelHandlerInterceptor.java Wed Mar 7 17:09:34 2012 @@ -21,6 +21,7 @@ package org.apache.rave.portal.web.inter import org.apache.rave.portal.service.PortalPreferenceService; import org.apache.rave.portal.web.util.ModelKeys; +import org.apache.rave.service.StaticContentFetcherService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.ui.ModelMap; @@ -36,10 +37,12 @@ import javax.servlet.http.HttpServletRes public class CommonModelHandlerInterceptor extends HandlerInterceptorAdapter { private final PortalPreferenceService preferenceService; + private final StaticContentFetcherService staticContentFetcherService; @Autowired - public CommonModelHandlerInterceptor(PortalPreferenceService preferenceService) { + public CommonModelHandlerInterceptor(PortalPreferenceService preferenceService, StaticContentFetcherService staticContentFetcherService) { this.preferenceService = preferenceService; + this.staticContentFetcherService = staticContentFetcherService; } @Override @@ -47,6 +50,7 @@ public class CommonModelHandlerIntercept if (modelAndView != null) { ModelMap map = modelAndView.getModelMap(); map.addAttribute(ModelKeys.PORTAL_SETTINGS, preferenceService.getPreferencesAsMap()); + map.addAttribute(ModelKeys.STATIC_CONTENT_CACHE, staticContentFetcherService); } super.postHandle(request, response, handler, modelAndView); } Copied: incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/tag/StaticContentTag.java (from r1297542, incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/tag/RegionWidgetTag.java) URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/tag/StaticContentTag.java?p2=incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/tag/StaticContentTag.java&p1=incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/tag/RegionWidgetTag.java&r1=1297542&r2=1298022&rev=1298022&view=diff ============================================================================== --- incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/tag/RegionWidgetTag.java (original) +++ incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/tag/StaticContentTag.java Wed Mar 7 17:09:34 2012 @@ -16,73 +16,40 @@ * specific language governing permissions and limitations * under the License. */ - package org.apache.rave.portal.web.tag; -import org.apache.commons.lang.StringEscapeUtils; -import org.apache.rave.portal.model.RegionWidget; -import org.apache.rave.portal.web.renderer.RenderScope; -import org.apache.rave.portal.web.renderer.RenderService; -import org.apache.rave.portal.web.renderer.ScriptLocation; -import org.apache.rave.portal.web.renderer.ScriptManager; - +import org.apache.rave.service.StaticContentFetcherService; import javax.servlet.jsp.JspException; /** - * JSP tag that renders a RegionWidget + * JSP tag that renders a block of static content from the StaticContentFetcherService cache */ -public class RegionWidgetTag extends AbstractContextAwareSingletonBeanDependentTag { - - private RegionWidget regionWidget; +public class StaticContentTag extends AbstractContextAwareSingletonBeanDependentTag { + private String contentKey; - // Script block for disabled gadget - private static final String DISABLED_SCRIPT_BLOCK = - ""; - - public RegionWidgetTag() { - super(RenderService.class); + public StaticContentTag() { + super(StaticContentFetcherService.class); } - public RegionWidget getRegionWidget() { - return regionWidget; + public String getContentKey() { + return contentKey; } - public void setRegionWidget(RegionWidget regionWidget) { - this.regionWidget = regionWidget; + public void setContentKey(String contentKey) { + this.contentKey = contentKey; } - /** - * Delegates rendering of the RegionWidget to the RenderService - * - * @return EVAL_BODY_INCLUDE if no exception is thrown - * @throws JspException if the regionWidget is not set or is not supported by the renderService. - */ @Override public int doStartTag() throws JspException { - - if (regionWidget != null && getBean().getSupportedWidgetTypes().contains(regionWidget.getWidget().getType()) ) { - if ( regionWidget.getWidget().isDisableRendering() ) { - ScriptManager scriptManager = getBeanFromContext(ScriptManager.class); - String widgetScript = String.format(DISABLED_SCRIPT_BLOCK, regionWidget.getRegion().getEntityId(), - regionWidget.getEntityId(), - StringEscapeUtils.escapeJavaScript(regionWidget.getWidget().getDisableRenderingMessage()), - regionWidget.isCollapsed(), - regionWidget.getWidget().getEntityId()); - scriptManager.registerScriptBlock(widgetScript, ScriptLocation.AFTER_RAVE, RenderScope.CURRENT_REQUEST, getContext()); - } else { - writeString(getBean().render(regionWidget, getContext())); - } + if (contentKey != null) { + writeString(getBean().getContent(contentKey)); } else { - throw new JspException("Unsupported regionWidget type or regionWidget not set: " + regionWidget); + throw new JspException("contentKey can't be null"); } - //Certain JSP implementations use tag pools. Setting the regionWidget to null ensures that there is no chance a given tag - //will accidentally re-use a region widget if the attribute in the JSP is empty - regionWidget = null; + //Certain JSP implementations use tag pools. Setting the contentKey to null ensures that there is no chance a given tag + //will accidentally re-use a contentKey if the attribute in the JSP is empty + contentKey = null; return EVAL_BODY_INCLUDE; } -} +} \ No newline at end of file Modified: incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/ModelKeys.java URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/ModelKeys.java?rev=1298022&r1=1298021&r2=1298022&view=diff ============================================================================== --- incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/ModelKeys.java (original) +++ incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/ModelKeys.java Wed Mar 7 17:09:34 2012 @@ -51,4 +51,5 @@ public class ModelKeys { public static final String DEFAULT_TAG_PAGE = "defaultTagPage"; public static final String CAPTCHA_HTML = "captchaHtml"; public static final String REDIRECT_MESSAGE = "message"; + public static final String STATIC_CONTENT_CACHE = "staticContentCache"; } \ No newline at end of file Modified: incubator/rave/trunk/rave-components/rave-web/src/main/resources/META-INF/rave.tld URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/main/resources/META-INF/rave.tld?rev=1298022&r1=1298021&r2=1298022&view=diff ============================================================================== --- incubator/rave/trunk/rave-components/rave-web/src/main/resources/META-INF/rave.tld (original) +++ incubator/rave/trunk/rave-components/rave-web/src/main/resources/META-INF/rave.tld Wed Mar 7 17:09:34 2012 @@ -50,4 +50,18 @@ org.apache.rave.portal.web.renderer.ScriptLocation + + Renders a static content fragment based on the cache key + render-static-content + org.apache.rave.portal.web.tag.StaticContentTag + JSP + + The cache key of the static content to render + contentKey + true + true + java.lang.String + + + Modified: incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/interceptors/CommonModelHandlerInterceptorTest.java URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/interceptors/CommonModelHandlerInterceptorTest.java?rev=1298022&r1=1298021&r2=1298022&view=diff ============================================================================== --- incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/interceptors/CommonModelHandlerInterceptorTest.java (original) +++ incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/interceptors/CommonModelHandlerInterceptorTest.java Wed Mar 7 17:09:34 2012 @@ -22,6 +22,7 @@ package org.apache.rave.portal.web.inter import org.apache.rave.portal.model.PortalPreference; import org.apache.rave.portal.service.PortalPreferenceService; import org.apache.rave.portal.web.util.ModelKeys; +import org.apache.rave.service.StaticContentFetcherService; import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; @@ -31,12 +32,9 @@ import org.springframework.web.servlet.M import java.util.HashMap; import java.util.Map; -import static junit.framework.Assert.assertNull; -import static junit.framework.Assert.assertTrue; -import static org.easymock.EasyMock.createMock; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.replay; -import static org.easymock.EasyMock.verify; +import static org.junit.Assert.*; +import static org.easymock.EasyMock.*; +import static org.hamcrest.CoreMatchers.*; /** * Test for {@link CommonModelHandlerInterceptor} @@ -45,11 +43,14 @@ public class CommonModelHandlerIntercept CommonModelHandlerInterceptor interceptor; PortalPreferenceService portalPreferenceService; + StaticContentFetcherService staticContentFetcherService; @Before public void setUp() throws Exception { portalPreferenceService = createMock(PortalPreferenceService.class); - interceptor = new CommonModelHandlerInterceptor(portalPreferenceService); + staticContentFetcherService = createMock(StaticContentFetcherService.class); + + interceptor = new CommonModelHandlerInterceptor(portalPreferenceService, staticContentFetcherService); } @Test @@ -66,7 +67,9 @@ public class CommonModelHandlerIntercept interceptor.postHandle(request, response, handler, modelAndView); verify(portalPreferenceService); - assertTrue(modelAndView.getModelMap().containsKey(ModelKeys.PORTAL_SETTINGS)); + Map modelMap = modelAndView.getModelMap(); + assertThat((Map) modelMap.get(ModelKeys.PORTAL_SETTINGS), sameInstance(preferenceMap)); + assertThat((StaticContentFetcherService) modelMap.get(ModelKeys.STATIC_CONTENT_CACHE), sameInstance(staticContentFetcherService)); } @Test public void testPostHandle_noModelAndView() throws Exception { @@ -76,6 +79,6 @@ public class CommonModelHandlerIntercept ModelAndView modelAndView = null; interceptor.postHandle(request, response, handler, modelAndView); - assertNull(modelAndView); + assertThat(modelAndView, is(nullValue(ModelAndView.class))); } } Added: incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/tag/StaticContentTagTest.java URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/tag/StaticContentTagTest.java?rev=1298022&view=auto ============================================================================== --- incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/tag/StaticContentTagTest.java (added) +++ incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/tag/StaticContentTagTest.java Wed Mar 7 17:09:34 2012 @@ -0,0 +1,90 @@ +/* + * 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.tag; + + +import org.apache.rave.service.StaticContentFetcherService; +import org.junit.Before; +import org.junit.Test; +import org.springframework.web.context.WebApplicationContext; + +import javax.servlet.ServletContext; +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.JspWriter; +import javax.servlet.jsp.PageContext; +import java.io.IOException; + +import static org.easymock.EasyMock.*; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.junit.Assert.assertThat; + +public class StaticContentTagTest { + private StaticContentFetcherService service; + private StaticContentTag tag; + private WebApplicationContext wContext; + private PageContext pageContext; + private ServletContext servletContext; + private JspWriter writer; + + private final String VALID_CACHE_KEY = "myCacheKey"; + private final String VALID_STATIC_CONTENT = "the content of the static content artifact"; + + @Before + public void setup() throws JspException { + service = createMock(StaticContentFetcherService.class); + wContext = createNiceMock(WebApplicationContext.class); + pageContext = createNiceMock(PageContext.class); + servletContext = createNiceMock(ServletContext.class); + writer = createNiceMock(JspWriter.class); + + tag = new StaticContentTag(); + tag.setPageContext(pageContext); + } + + @Test + public void doStartTag_validKey() throws IOException, JspException { + tag.setContentKey(VALID_CACHE_KEY); + + expect(service.getContent(VALID_CACHE_KEY)).andReturn(VALID_STATIC_CONTENT); + expect(pageContext.getServletContext()).andReturn(servletContext).anyTimes(); + expect(servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)).andReturn(wContext).anyTimes(); + expect(wContext.getBean(StaticContentFetcherService.class)).andReturn(service).anyTimes(); + expect(pageContext.getOut()).andReturn(writer); + replay(service, pageContext, servletContext, wContext, writer); + + int result = tag.doStartTag(); + + assertThat(result, is(javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE)); + verify(service, pageContext, servletContext, wContext, writer); + } + + @Test(expected = JspException.class) + public void doStartTag_nullKey() throws IOException, JspException { + tag.setContentKey(null); + tag.doStartTag(); + } + + @Test + public void getCacheKey() { + assertThat(tag.getContentKey(), is(nullValue(String.class))); + tag.setContentKey(VALID_CACHE_KEY); + assertThat(tag.getContentKey(), is(VALID_CACHE_KEY)); + } +} Modified: incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/common/header.jsp URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/common/header.jsp?rev=1298022&r1=1298021&r2=1298022&view=diff ============================================================================== --- incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/common/header.jsp (original) +++ incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/common/header.jsp Wed Mar 7 17:09:34 2012 @@ -16,4 +16,9 @@ KIND, either express or implied. See th specific language governing permissions and limitations under the License. --%> -<%-- Common header will go here... --%> \ No newline at end of file +<%-- Common header will go here... --%> + +<%-- example on how to render static content from the cache using the tag library +<%@ include file="/WEB-INF/jsp/includes/taglibs.jsp" %> + +--%> \ No newline at end of file