001/*
002 *  Copyright 2014 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.tags.observers;
017
018import java.util.Collection;
019import java.util.Map;
020
021import org.apache.avalon.framework.service.ServiceException;
022import org.apache.avalon.framework.service.ServiceManager;
023import org.apache.commons.collections.CollectionUtils;
024
025import org.ametys.cms.ObservationConstants;
026import org.ametys.cms.repository.Content;
027import org.ametys.cms.repository.ContentQueryHelper;
028import org.ametys.cms.tag.TagProviderExtensionPoint;
029import org.ametys.cms.tag.jcr.JCRTag;
030import org.ametys.core.observation.Event;
031import org.ametys.core.observation.Observer;
032import org.ametys.plugins.repository.AmetysObject;
033import org.ametys.plugins.repository.AmetysObjectIterable;
034import org.ametys.plugins.repository.EmptyIterable;
035import org.ametys.plugins.repository.query.expression.Expression.Operator;
036import org.ametys.web.cache.CacheHelper;
037import org.ametys.web.indexing.observation.AbstractLiveSolrObserver;
038import org.ametys.web.repository.site.Site;
039import org.ametys.web.tags.TagExpression;
040import org.ametys.web.tags.TagExpression.LogicalOperator;
041
042/**
043 * Abstract tag {@link Observer}
044 */
045public abstract class AbstractTagObserver extends AbstractLiveSolrObserver
046{
047    /** The tag provider EP */
048    protected TagProviderExtensionPoint _tagProviderEP;
049    
050    @Override
051    public void service(ServiceManager manager) throws ServiceException
052    {
053        super.service(manager);
054        _tagProviderEP = (TagProviderExtensionPoint) manager.lookup(TagProviderExtensionPoint.ROLE);
055    }
056    
057    @Override
058    protected void _updateIndex(Event event, Map<String, Object> transientVars) throws Exception
059    {
060        Map<String, Object> arguments = event.getArguments();
061        AmetysObject tagOrParent = (JCRTag) arguments.get(ObservationConstants.ARGS_TAG);
062        
063        if (tagOrParent == null)
064        {
065            tagOrParent = (AmetysObject) arguments.get("tag.parent");
066        }
067        
068        String tagName = (String) arguments.get(ObservationConstants.ARGS_TAG_NAME);
069        
070        observe(_getSite(tagOrParent), tagOrParent, tagName, event);
071    }
072    
073    /**
074     * Typed observe method
075     * @param site the site
076     * @param tagOrParent  the tag or its parent
077     * @param tagName the tag name corresponding the the object tagOrParent when applicable.
078     * @param rawEvent The raw event from which the previous arguments have been extracted.
079     */
080    protected abstract void observe(Site site, AmetysObject tagOrParent, String tagName, Event rawEvent);
081    
082    /**
083     * Get the site of a jcr tag.
084     * @param tagOrParent Ametys object which can be a tag or its parent depending on the event type.
085     * @return The site
086     */
087    protected Site _getSite(AmetysObject tagOrParent)
088    {
089        AmetysObject ao = tagOrParent;
090        
091        while (ao != null)
092        {
093            if (ao instanceof Site)
094            {
095                return (Site) ao; 
096            }
097            ao = ao.getParent();
098        }
099        
100        return null;
101    }
102    
103    /**
104     * Clear site cache
105     * @param site the site
106     */
107    protected void _clearCache(Site site)
108    {
109        try
110        {
111            if (site != null)
112            {
113                CacheHelper.invalidateCache(site, getLogger());
114            }
115        }
116        catch (Exception e)
117        {
118            getLogger().error("Unable to invalidate cache for site : " + site, e);
119        }
120    }
121    
122    /**
123     * Re-index content tagged with at least of this tags
124     * @param descendantNames the descendant tags' name
125     * @return iterable on contents
126     * @throws Exception if an error occurs
127     */
128    protected AmetysObjectIterable<Content> _getTaggedContents(Collection<String> descendantNames) throws Exception
129    {
130        if (CollectionUtils.isEmpty(descendantNames))
131        {
132            return new EmptyIterable<>();
133        }
134        
135        TagExpression tagExpression = new TagExpression(Operator.EQ, descendantNames.toArray(new String[descendantNames.size()]), LogicalOperator.OR);
136        String contentXPathQuery = ContentQueryHelper.getContentXPathQuery(tagExpression);
137        
138        return _resolver.query(contentXPathQuery);
139    }
140}