001/*
002 *  Copyright 2017 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.plugins.workspaces.indexing.solr;
017
018import org.apache.avalon.framework.context.Context;
019import org.apache.avalon.framework.context.ContextException;
020import org.apache.avalon.framework.context.Contextualizable;
021import org.apache.avalon.framework.service.ServiceException;
022import org.apache.avalon.framework.service.ServiceManager;
023import org.apache.avalon.framework.service.Serviceable;
024import org.apache.cocoon.components.ContextHelper;
025import org.apache.cocoon.environment.Request;
026import org.apache.solr.client.solrj.SolrClient;
027
028import org.ametys.cms.indexing.IndexingException;
029import org.ametys.cms.indexing.solr.DocumentProvider;
030import org.ametys.core.schedule.progression.ContainerProgressionTracker;
031import org.ametys.core.schedule.progression.ProgressionTrackerFactory;
032import org.ametys.core.schedule.progression.SimpleProgressionTracker;
033import org.ametys.plugins.explorer.resources.ModifiableResourceCollection;
034import org.ametys.plugins.repository.AmetysObjectIterable;
035import org.ametys.plugins.repository.provider.RequestAttributeWorkspaceSelector;
036import org.ametys.plugins.workspaces.documents.DocumentWorkspaceModule;
037import org.ametys.plugins.workspaces.project.ProjectManager;
038import org.ametys.plugins.workspaces.project.modules.WorkspaceModuleExtensionPoint;
039import org.ametys.plugins.workspaces.project.objects.Project;
040import org.ametys.runtime.i18n.I18nizableText;
041import org.ametys.runtime.plugin.component.AbstractLogEnabled;
042
043/**
044 * {@link DocumentProvider} for indexing documents (project resources...) during workspace indexation
045 */
046public class ProjectDocumentProvider extends AbstractLogEnabled implements DocumentProvider, Serviceable, Contextualizable
047{
048    private static final I18nizableText __LABEL = new I18nizableText("plugin.workspaces", "PLUGINS_WORKSPACES_CONTENT_INDEXING_PROJETDOCUMENTPROVIDER"); 
049    /** The manager for {@link Project}s */
050    protected ProjectManager _projectManager;
051    /** The Solr indexer for project resources */
052    protected SolrProjectResourceIndexer _solrProjectResourceIndexer;
053    /** The manager for documents */
054    protected DocumentWorkspaceModule _documentModule;
055    
056    /** The component context. */
057    protected Context _context;
058    
059    @Override
060    public void contextualize(Context context) throws ContextException
061    {
062        _context = context;
063    }
064    
065    @Override
066    public void service(ServiceManager manager) throws ServiceException
067    {
068        _projectManager = (ProjectManager) manager.lookup(ProjectManager.ROLE);
069        _solrProjectResourceIndexer = (SolrProjectResourceIndexer) manager.lookup(SolrProjectResourceIndexer.ROLE);
070        WorkspaceModuleExtensionPoint moduleManager = (WorkspaceModuleExtensionPoint) manager.lookup(WorkspaceModuleExtensionPoint.ROLE);
071        _documentModule = moduleManager.getModule(DocumentWorkspaceModule.DOCUMENT_MODULE_ID);
072    }
073    
074    public I18nizableText getLabel()
075    {
076        return __LABEL;
077    }
078    
079    public void indexDocuments(String workspaceName, SolrClient solrClient) throws IndexingException
080    {
081        indexDocuments(workspaceName, solrClient, ProgressionTrackerFactory.createContainerProgressionTracker("Index documents", getLogger()));
082    }
083    
084    public void indexDocuments(String workspaceName, SolrClient solrClient, ContainerProgressionTracker progressionTracker) throws IndexingException
085    {
086        Request request = ContextHelper.getRequest(_context);
087        String currentWsp = RequestAttributeWorkspaceSelector.getForcedWorkspace(request);
088        
089        try
090        {
091            // Force the workspace.
092            RequestAttributeWorkspaceSelector.setForcedWorkspace(request, workspaceName);
093            
094            _indexProjects(workspaceName, solrClient, progressionTracker);
095        }
096        finally
097        {
098            // Restore context
099            RequestAttributeWorkspaceSelector.setForcedWorkspace(request, currentWsp);
100        }
101    }
102    
103    private void _indexProjects(String workspaceName, SolrClient solrClient, ContainerProgressionTracker progressionTracker) throws IndexingException
104    {
105        AmetysObjectIterable<Project> projects = _projectManager.getProjects();
106
107        
108        if (projects.getSize() == 0)
109        {
110            progressionTracker.addSimpleStep("noprojects", new I18nizableText("")).setSize(0);
111        }
112        else
113        {
114            for (Project project : projects)
115            {
116                progressionTracker.addSimpleStep(project.getName(), new I18nizableText(project.getName()));
117            }
118            
119            for (Project project : projects)
120            {
121                _indexProject(workspaceName, project, solrClient, progressionTracker.getStep(project.getName()));
122            }
123        }
124    }
125    
126    private void _indexProject(String workspaceName, Project project, SolrClient solrClient, SimpleProgressionTracker progressionTracker) throws IndexingException
127    {
128        try
129        {
130            // Index the documents
131            ModifiableResourceCollection documentRoot = _documentModule.getModuleRoot(project, false);
132            getLogger().info("Starting indexation of project resources for project {} ('{}') in workspace {}", project.getName(), project.getId(), workspaceName);
133            
134            _solrProjectResourceIndexer.indexProjectResources(documentRoot, project, solrClient, progressionTracker);
135        }
136        catch (Exception e)
137        {
138            String error = String.format("Failed to index project %s in workspace %s", project.getName(), workspaceName);
139            getLogger().error(error, e);
140            throw new IndexingException(error, e);
141        }
142    }
143}