001/* 002 * Copyright 2015 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.web.cache; 017 018import java.util.ArrayList; 019import java.util.Collection; 020import java.util.Iterator; 021import java.util.List; 022 023import org.apache.avalon.framework.component.Component; 024import org.apache.avalon.framework.logger.AbstractLogEnabled; 025import org.apache.avalon.framework.service.ServiceException; 026import org.apache.avalon.framework.service.ServiceManager; 027import org.apache.avalon.framework.service.Serviceable; 028 029import org.ametys.cms.repository.Content; 030import org.ametys.core.right.RightManager; 031import org.ametys.plugins.repository.AmetysObjectIterable; 032import org.ametys.web.inputdata.InputData; 033import org.ametys.web.inputdata.InputDataExtensionPoint; 034import org.ametys.web.repository.page.Page; 035import org.ametys.web.repository.page.Page.PageType; 036import org.ametys.web.repository.page.Zone; 037import org.ametys.web.repository.page.ZoneItem; 038import org.ametys.web.repository.page.ZoneItem.ZoneType; 039import org.ametys.web.repository.site.Site; 040import org.ametys.web.service.Service; 041import org.ametys.web.service.ServiceExtensionPoint; 042 043/** 044 * Helper component providing status of pages. 045 */ 046public class PageHelper extends AbstractLogEnabled implements Component, Serviceable 047{ 048 /** The component role. */ 049 public static final String ROLE = PageHelper.class.getName(); 050 051 private ServiceExtensionPoint _serviceExtPt; 052 private RightManager _rightManager; 053 private InputDataExtensionPoint _inputDataExtensionPoint; 054 055 @Override 056 public void service(ServiceManager serviceManager) throws ServiceException 057 { 058 _serviceExtPt = (ServiceExtensionPoint) serviceManager.lookup(ServiceExtensionPoint.ROLE); 059 _rightManager = (RightManager) serviceManager.lookup(RightManager.ROLE); 060 _inputDataExtensionPoint = (InputDataExtensionPoint) serviceManager.lookup(InputDataExtensionPoint.ROLE); 061 } 062 063 /** 064 * Tests if a page is cacheable, i.e:<ul> 065 * <li>its access is not restricted</li> 066 * <li>all its page elements are cachable</li> 067 * </ul> 068 * @param page The page to test. 069 * @return true if the page is cachable, false otherwise. 070 */ 071 public boolean isCacheable(Page page) 072 { 073 if (!_rightManager.hasAnonymousReadAccess(page)) 074 { 075 // never cache a private page 076 return false; 077 } 078 079 if (page.getType() != PageType.CONTAINER) 080 { 081 // makes no sense to cache a Node or link page 082 return false; 083 } 084 085 boolean isCacheable = true; 086 AmetysObjectIterable<? extends Zone> zones = page.getZones(); 087 Iterator<? extends Zone> itZ = zones.iterator(); 088 089 // test each service of the page 090 while (isCacheable && itZ.hasNext()) 091 { 092 Zone zone = itZ.next(); 093 AmetysObjectIterable<? extends ZoneItem> zoneItems = zone.getZoneItems(); 094 Iterator<? extends ZoneItem> itZI = zoneItems.iterator(); 095 096 while (isCacheable && itZI.hasNext()) 097 { 098 ZoneItem zoneItem = itZI.next(); 099 if (zoneItem.getType() == ZoneType.SERVICE) 100 { 101 Service service = _serviceExtPt.getExtension(zoneItem.getServiceId()); 102 try 103 { 104 isCacheable = service != null && service.isCacheable(page, zoneItem); 105 } 106 catch (Exception e) 107 { 108 // Ignore 109 } 110 } 111 } 112 } 113 114 // Test each inputdata 115 if (isCacheable) 116 { 117 Collection<String> ids = _inputDataExtensionPoint.getExtensionsIds(); 118 Iterator<String> it = ids.iterator(); 119 while (isCacheable && it.hasNext()) 120 { 121 String id = it.next(); 122 InputData inputData = _inputDataExtensionPoint.getExtension(id); 123 isCacheable = inputData.isCacheable(page.getSite(), page); 124 } 125 } 126 127 return isCacheable; 128 } 129 130 /** 131 * Determines if a captcha is required on forms of the page 132 * @param page The page to test 133 * @return true if a captcha is required 134 */ 135 public boolean isCaptchaRequired (Page page) 136 { 137 Site site = page.getSite(); 138 139 String captchaPolicy = site.getValue("display-captcha-policy"); 140 141 if (captchaPolicy == null || "restricted".equals(captchaPolicy)) 142 { 143 // Display captcha on public page only 144 return _rightManager.hasAnonymousReadAccess(page); 145 } 146 147 return "always".equals(captchaPolicy); 148 } 149 150 /** 151 * Get all the contents inside a page 152 * @param page page to search 153 * @return list of contents in this page 154 */ 155 public List<Content> getAllContents (Page page) 156 { 157 List<Content> result = new ArrayList<>(); 158 AmetysObjectIterable< ? extends Zone> zones = page.getZones(); 159 for (Zone zone : zones) 160 { 161 AmetysObjectIterable< ? extends ZoneItem> zoneItems = zone.getZoneItems(); 162 for (ZoneItem zoneItem : zoneItems) 163 { 164 if (ZoneType.CONTENT.equals(zoneItem.getType())) 165 { 166 Content content = zoneItem.getContent(); 167 result.add(content); 168 } 169 } 170 } 171 return result; 172 } 173 174}