001/* 002 * Copyright 2016 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.plugins.userdirectory.observation; 018 019import java.util.Map; 020 021import org.apache.avalon.framework.context.ContextException; 022import org.apache.avalon.framework.context.Contextualizable; 023import org.apache.avalon.framework.service.ServiceException; 024import org.apache.avalon.framework.service.ServiceManager; 025import org.apache.avalon.framework.service.Serviceable; 026import org.apache.cocoon.environment.Context; 027import org.apache.commons.lang3.ArrayUtils; 028 029import org.ametys.cms.ObservationConstants; 030import org.ametys.cms.contenttype.ContentTypesHelper; 031import org.ametys.cms.repository.Content; 032import org.ametys.core.observation.Event; 033import org.ametys.core.observation.Observer; 034import org.ametys.plugins.repository.AmetysObjectIterable; 035import org.ametys.plugins.repository.AmetysObjectResolver; 036import org.ametys.plugins.repository.query.expression.Expression; 037import org.ametys.plugins.repository.query.expression.VirtualFactoryExpression; 038import org.ametys.plugins.userdirectory.UserDirectoryPageHandler; 039import org.ametys.plugins.userdirectory.page.VirtualUserDirectoryPageFactory; 040import org.ametys.runtime.plugin.component.AbstractLogEnabled; 041import org.ametys.web.repository.page.Page; 042import org.ametys.web.repository.page.PageQueryHelper; 043 044/** 045 * Abstract {@link Observer} for observing validation of User content. 046 */ 047public abstract class AbstractUserObserver extends AbstractLogEnabled implements Observer, Serviceable, Contextualizable 048{ 049 /** The context. */ 050 protected org.apache.avalon.framework.context.Context _context; 051 /** Cocoon context. */ 052 protected Context _cocoonContext; 053 /** Ametys object resolver. */ 054 protected AmetysObjectResolver _resolver; 055 /** The content type helper */ 056 protected ContentTypesHelper _contentTypeHelper; 057 058 @Override 059 public void contextualize(org.apache.avalon.framework.context.Context context) throws ContextException 060 { 061 _context = context; 062 _cocoonContext = (Context) context.get(org.apache.cocoon.Constants.CONTEXT_ENVIRONMENT_CONTEXT); 063 } 064 065 @Override 066 public void service(ServiceManager manager) throws ServiceException 067 { 068 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 069 _contentTypeHelper = (ContentTypesHelper) manager.lookup(ContentTypesHelper.ROLE); 070 } 071 072 @Override 073 public void observe(Event event, Map<String, Object> transientVars) 074 { 075 try 076 { 077 Content userContent = _getUserContent(event); 078 if (userContent == null) 079 { 080 // The event does not concern a user content 081 return; 082 } 083 084 AmetysObjectIterable<Page> rootPages = _getUserDirectoryRootPages (); 085 if (!rootPages.iterator().hasNext()) 086 { 087 getLogger().debug("There's no user directory root page, nothing to invalidate"); 088 return; 089 } 090 091 for (Page rootPage : rootPages) 092 { 093 String cType = rootPage.getMetadataHolder().getString(UserDirectoryPageHandler.CONTENT_TYPE_METADATA_NAME, null); 094 if (ArrayUtils.contains(userContent.getTypes(), cType)) 095 { 096 _internalObserve(event, rootPage, userContent); 097 } 098 } 099 } 100 catch (Exception e) 101 { 102 getLogger().error("Unable to observe event: " + event, e); 103 } 104 } 105 106 /** 107 * Do the actual work. 108 * @param event the observation event. 109 * @param rootUsersPage the page holding the virtual user pages 110 * @param userContent a list containing all impacted user contents. 111 */ 112 protected abstract void _internalObserve(Event event, Page rootUsersPage, Content userContent); 113 114 /** 115 * Get the user directory root pages 116 * @return the user directory root pages 117 */ 118 protected AmetysObjectIterable<Page> _getUserDirectoryRootPages () 119 { 120 Expression expression = new VirtualFactoryExpression(VirtualUserDirectoryPageFactory.class.getName()); 121 String query = PageQueryHelper.getPageXPathQuery(null, null, null, expression, null); 122 123 return _resolver.query(query); 124 } 125 126 /** 127 * Retrieve the target of the observer 128 * @param event The event 129 * @return The target 130 * @throws Exception if failed to get content 131 */ 132 protected Content _getTarget(Event event) throws Exception 133 { 134 return (Content) event.getArguments().get(ObservationConstants.ARGS_CONTENT); 135 } 136 137 /** 138 * Get the target user content 139 * @param event the event 140 * @return the target user content or null if content if not the user content 141 * @throws Exception if failed to get content 142 */ 143 protected Content _getUserContent(Event event) throws Exception 144 { 145 Content content = _getTarget(event); 146 147 if (_contentTypeHelper.isInstanceOf(content, UserDirectoryPageHandler.ABSTRACT_USER_CONTENT_TYPE)) 148 { 149 return content; 150 } 151 152 return null; 153 } 154}