001/* 002 * Copyright 2010 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 */ 016 017package org.ametys.site; 018 019import java.util.Map; 020import java.util.UUID; 021 022import org.apache.avalon.framework.parameters.Parameters; 023import org.apache.avalon.framework.service.ServiceException; 024import org.apache.avalon.framework.service.ServiceManager; 025import org.apache.avalon.framework.thread.ThreadSafe; 026import org.apache.cocoon.acting.ServiceableAction; 027import org.apache.cocoon.environment.ObjectModelHelper; 028import org.apache.cocoon.environment.Redirector; 029import org.apache.cocoon.environment.Request; 030import org.apache.cocoon.environment.SourceResolver; 031import org.apache.commons.lang.StringUtils; 032import org.apache.excalibur.source.Source; 033import org.apache.excalibur.source.SourceNotFoundException; 034import org.apache.excalibur.source.TraversableSource; 035import org.apache.excalibur.source.impl.FileSource; 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038 039import org.ametys.plugins.site.cache.monitoring.Constants; 040import org.ametys.plugins.site.cache.monitoring.process.access.ResourceAccessComponent; 041import org.ametys.plugins.site.cache.monitoring.process.access.impl.FrontResourceAccess; 042 043/** 044 * The cocoon resource exists action but that returns false for folders 045 */ 046public class ResourceExistsAction extends ServiceableAction implements ThreadSafe 047{ 048 /** The resource access monitoring component */ 049 protected ResourceAccessComponent _resourceAccessComponent; 050 051 // FIXME static final logger? 052 private final Logger _logger = LoggerFactory.getLogger("site.cache.log"); 053 054 @Override 055 public void service(ServiceManager serviceManager) throws ServiceException 056 { 057 super.service(serviceManager); 058 _resourceAccessComponent = (ResourceAccessComponent) serviceManager.lookup(ResourceAccessComponent.ROLE); 059 } 060 061 @Override 062 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String src, Parameters parameters) throws Exception 063 { 064 String resourceURI = parameters.getParameter("url", src); 065 Source source = null; 066 067 // Resource monitoring 068 // the Apache mod_unique_id set a request header "UNIQUE_ID" 069 // that we could use to track request in log files 070 Request request = ObjectModelHelper.getRequest(objectModel); 071 String uniqueId = request.getHeader("UNIQUE_ID"); 072 073 // Set the random uuid as a request attribute to be added later in the possible requests to the BO. 074 String uuid = UUID.randomUUID().toString(); 075 request.setAttribute("Monitoring-UUID", uuid); 076 077 String path = resourceURI; 078 if (StringUtils.startsWith(path, "ametys-home://cache")) 079 { 080 path = StringUtils.removeStart(path, "ametys-home://cache"); 081 } 082 else 083 { 084 path = StringUtils.removeStart(resourceURI, SiteCacheHelper.getRootCache().getPath()); 085 } 086 087 FrontResourceAccess fra = new FrontResourceAccess(uniqueId, uuid, parameters.getParameter("site", null), path); 088 089 try 090 { 091 source = resolver.resolveURI(resourceURI); 092 093 if (source instanceof FileSource && !SiteCacheHelper.isValid((FileSource) source)) 094 { 095 // Release the old source and replace it by a hashed file source. 096 source = SiteCacheHelper.getHashedFileSource(resolver, (FileSource) source); 097 } 098 099 if (source.exists() 100 && (!(source instanceof TraversableSource) || !((TraversableSource) source).isCollection())) 101 { 102 if (_logger.isDebugEnabled()) 103 { 104 _logger.debug("Find resource '" + resourceURI + " in cache"); 105 } 106 107 fra.setCacheable(true); 108 fra.setCacheHit1(true); 109 _resourceAccessComponent.addAccessRecord(fra); 110 111 return EMPTY_MAP; 112 } 113 } 114 catch (SourceNotFoundException e) 115 { 116 // Do not log 117 } 118 catch (Exception e) 119 { 120 getLogger().warn("Exception resolving resource " + resourceURI, e); 121 } 122 finally 123 { 124 if (source != null) 125 { 126 resolver.release(source); 127 } 128 } 129 130 fra.setCacheHit1(false); 131 request.setAttribute(Constants.REQUEST_ATTRIBUTE_PAGEACCESS, fra); 132 133 return null; 134 } 135 136}