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.web.live;
018
019import java.util.ArrayList;
020import java.util.List;
021import java.util.Map;
022
023import javax.jcr.Node;
024import javax.jcr.NodeIterator;
025import javax.jcr.RepositoryException;
026import javax.jcr.Session;
027
028import org.apache.avalon.framework.logger.AbstractLogEnabled;
029import org.apache.avalon.framework.service.ServiceException;
030import org.apache.avalon.framework.service.ServiceManager;
031import org.apache.avalon.framework.service.Serviceable;
032import org.slf4j.Logger;
033
034import org.ametys.core.schedule.progression.ContainerProgressionTracker;
035import org.ametys.core.schedule.progression.SimpleProgressionTracker;
036import org.ametys.core.util.AvalonLoggerAdapter;
037import org.ametys.plugins.repository.AmetysObjectIterable;
038import org.ametys.runtime.i18n.I18nizableText;
039import org.ametys.web.repository.site.Site;
040import org.ametys.web.repository.site.SiteManager;
041import org.ametys.web.skin.Skin;
042import org.ametys.web.skin.SkinsManager;
043
044/**
045 * {@link LivePopulator} for synchronizing sites.
046 */
047public class SitesLivePopulator extends AbstractLogEnabled implements LivePopulator, Serviceable
048{
049    private static final I18nizableText __LABEL = new I18nizableText("plugin.web", "PLUGINS_WEB_SCHEDULABLE_REBUILD_LIVE_SITESLIVEPOPULATOR");
050    
051    
052    private SitePopulator _sitePopulator;
053    private SkinsManager _skinsManager;
054    private SiteManager _siteManager;
055    
056    @Override
057    public void service(ServiceManager manager) throws ServiceException
058    {
059        _sitePopulator = (SitePopulator) manager.lookup(SitePopulator.ROLE);
060        _skinsManager = (SkinsManager) manager.lookup(SkinsManager.ROLE);
061        _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE);
062    }
063    
064    public I18nizableText getLabel()
065    {
066        return __LABEL;
067    }
068    
069    @Override
070    public Logger getProgressionTrackerLogger()
071    {
072        return new AvalonLoggerAdapter(getLogger());
073    }
074    
075    private void _prepareProgressionTrackerStepsForPopulate(AmetysObjectIterable<Site> siteIterable , ContainerProgressionTracker progressionTracker)
076    {
077        progressionTracker.addSimpleStep("delete", new I18nizableText("plugin.web", "PLUGINS_WEB_SCHEDULABLE_REBUILD_LIVE_DELETE_LIVE_SITES_STEP_LABEL"));
078        ContainerProgressionTracker populateSiteProgressionTracker = progressionTracker.addContainerStep("sites", new I18nizableText("plugin.web", "PLUGINS_WEB_SCHEDULABLE_REBUILD_LIVE_POPULATE_SITES_STEP_LABEL"));
079        
080        for (Site site : siteIterable)
081        {
082            populateSiteProgressionTracker.addContainerStep(site.getName(), new I18nizableText("plugin.web", "PLUGINS_WEB_SCHEDULABLE_REBUILD_LIVE_POPULATE_SITE_STEP_LABEL", Map.of("siteName", new I18nizableText(site.getName()))));
083        }
084    }
085    
086    @Override
087    public List<String> populate(Session session, Session liveSession, ContainerProgressionTracker progressionTracker)
088    {
089        AmetysObjectIterable<Site> siteIterable = _siteManager.getSites();
090        
091        _prepareProgressionTrackerStepsForPopulate(siteIterable, progressionTracker);
092        
093        List<String> errors = new ArrayList<>(); 
094        
095        // First delete sites in live (to avoid that a deleted site in workspace default still remains in live workspace)
096        errors.addAll(_deleteLiveSites(liveSession, progressionTracker.getStep("delete")));
097        
098        ContainerProgressionTracker populateSiteProgressionTracker = progressionTracker.getStep("sites");
099        
100        ContainerProgressionTracker subStepTracker;
101        for (Site site : siteIterable)
102        {
103            subStepTracker = populateSiteProgressionTracker.getStep(site.getName());
104
105            try
106            {
107                if (getLogger().isInfoEnabled())
108                {
109                    getLogger().info("Populate live workspace for site " + site.getName());
110                }
111                
112                Skin skin = _skinsManager.getSkin(site.getSkinId());
113                
114                if (skin == null)
115                {
116                    throw new IllegalArgumentException("There's no skin for site " + site.getName() + ". Unable to rebuild live workspace.");
117                }
118                
119                _sitePopulator.populate(site, skin, subStepTracker);
120            }
121            catch (Exception e)
122            {
123                errors.add("Unable to populate live workspace for site: " + site.getName() + "\n" + e.getMessage());
124                getLogger().error("Unable to populate live workspace for site: " + site.getName(), e);
125            }
126        }
127        
128        return errors;
129    }
130    
131    private List<String> _deleteLiveSites(Session liveSession, SimpleProgressionTracker progressionTracker)
132    {
133        List<String> errors = new ArrayList<>();
134
135        try
136        {
137            if (getLogger().isInfoEnabled())
138            {
139                getLogger().info("Remove all sites from live");
140            }
141            
142            Node liveRootNode = liveSession.getRootNode();
143            if (liveRootNode.hasNode("ametys:root" + SiteManager.ROOT_SITES_PATH))
144            {
145                NodeIterator childNodes = liveRootNode.getNode("ametys:root" + SiteManager.ROOT_SITES_PATH).getNodes();
146                while (childNodes.hasNext())
147                {
148                    Node siteNode = childNodes.nextNode();
149                    siteNode.remove();
150                }
151            }
152        }
153        catch (RepositoryException e)
154        {
155            errors.add("Failed to delete all sites from live workspace\n" + e.getMessage());
156            getLogger().error("Failed to delete all sites from live workspace", e);
157        }
158        
159        progressionTracker.increment();
160        
161        return errors;
162    }
163}