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 */
016package org.ametys.web.live;
017
018import java.util.HashMap;
019import java.util.Map;
020
021import javax.jcr.Repository;
022
023import org.apache.avalon.framework.CascadingRuntimeException;
024import org.apache.avalon.framework.component.WrapperComponentManager;
025import org.apache.avalon.framework.context.Context;
026import org.apache.avalon.framework.context.ContextException;
027import org.apache.avalon.framework.service.ServiceException;
028import org.apache.avalon.framework.service.ServiceManager;
029import org.apache.cocoon.Constants;
030import org.apache.cocoon.Processor;
031import org.apache.cocoon.components.CocoonComponentManager;
032import org.apache.cocoon.environment.background.BackgroundEnvironment;
033import org.apache.cocoon.util.log.SLF4JLoggerAdapter;
034import org.quartz.JobExecutionContext;
035
036import org.ametys.cms.schedule.AbstractSendingMailSchedulable;
037
038/**
039 * Abstract schedulable for rebuilding the live workspace.
040 */
041public abstract class AbstractRebuildLiveWorkspaceSchedulable extends AbstractSendingMailSchedulable
042{
043    /** The cocoon environment context. */
044    protected org.apache.cocoon.environment.Context _environmentContext;
045    /** Component for rebuilding the live workspace */
046    protected RebuildLiveComponent _rebuildLiveComponent;
047    /** JCR repository */
048    protected Repository _repository;
049    
050    @Override
051    public void contextualize(Context context) throws ContextException
052    {
053        super.contextualize(context);
054        _environmentContext = (org.apache.cocoon.environment.Context) context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
055    }
056    
057    @Override
058    public void service(ServiceManager manager) throws ServiceException
059    {
060        super.service(manager);
061        _rebuildLiveComponent = (RebuildLiveComponent) manager.lookup(RebuildLiveComponent.ROLE);
062        _repository = (Repository) manager.lookup(Repository.class.getName());
063    }
064    
065    @Override
066    protected void _doExecute(JobExecutionContext context) throws Exception
067    {
068        getLogger().info("Time to rebuild live workspace");
069        
070        // Create environment
071        Map<String, Object> env = _createAndEnterGenerationEnvironment();
072        
073        try
074        {
075            _rebuildLiveWorkspace(context);
076        }
077        finally
078        {
079            _leaveGenerationEnvironment(env);
080        }
081    }
082    
083    /**
084     * Implements this method for building the live.
085     * @param context the context
086     * @throws Exception if an error occurred
087     */
088    protected abstract void _rebuildLiveWorkspace(JobExecutionContext context) throws Exception;
089    
090    private Map<String, Object> _createAndEnterGenerationEnvironment()
091    {
092        BackgroundEnvironment environment;
093        Processor processor;
094
095        try
096        {
097            environment = new BackgroundEnvironment(new SLF4JLoggerAdapter(getLogger()), _environmentContext);
098            processor = (Processor) _smanager.lookup(Processor.ROLE);
099        }
100        catch (Exception e)
101        {
102            throw new CascadingRuntimeException("Error during environment's setup.", e);
103        }
104
105        Object processingKey = CocoonComponentManager.startProcessing(environment);
106        int environmentDepth = CocoonComponentManager.markEnvironment();
107
108        CocoonComponentManager.enterEnvironment(environment, new WrapperComponentManager(_smanager), processor);
109
110        Map<String, Object> result = new HashMap<>();
111
112        result.put("environment", environment);
113        result.put("processor", processor);
114        result.put("processingKey", processingKey);
115        result.put("environmentDepth", Integer.valueOf(environmentDepth));
116
117        return result;
118    }
119
120    private void _leaveGenerationEnvironment(Map environmentInformation)
121    {
122        BackgroundEnvironment environment = (BackgroundEnvironment) environmentInformation.get("environment");
123        Processor processor = (Processor) environmentInformation.get("processor");
124        Object processingKey = environmentInformation.get("processingKey");
125        int environmentDepth = ((Integer) environmentInformation.get("environmentDepth")).intValue();
126
127        CocoonComponentManager.leaveEnvironment();
128        CocoonComponentManager.endProcessing(environment, processingKey);
129
130        try
131        {
132            CocoonComponentManager.checkEnvironment(environmentDepth, new SLF4JLoggerAdapter(getLogger()));
133        }
134        catch (Exception e)
135        {
136            throw new CascadingRuntimeException("Error checking the environment", e);
137        }
138
139        _smanager.release(processor);
140    }
141}