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 */
016package org.ametys.web.site;
017
018import java.io.IOException;
019import java.util.ArrayList;
020import java.util.List;
021import java.util.Set;
022import java.util.regex.Matcher;
023import java.util.regex.Pattern;
024
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.cocoon.ProcessingException;
028import org.apache.cocoon.generation.ServiceableGenerator;
029import org.apache.cocoon.xml.AttributesImpl;
030import org.apache.cocoon.xml.XMLUtils;
031import org.xml.sax.SAXException;
032
033import org.ametys.core.user.population.PopulationContextHelper;
034import org.ametys.plugins.repository.AmetysObjectIterable;
035import org.ametys.web.repository.site.Site;
036import org.ametys.web.repository.site.SiteManager;
037import org.ametys.web.repository.sitemap.Sitemap;
038
039/**
040 * SAXes sites front-office configuration.
041 */
042public class SitesGenerator extends ServiceableGenerator
043{
044    /** Pattern for sites URL. */
045    public static final Pattern URL_PATTERN = Pattern.compile("^(https?)://([a-zA-Z0-9.\\-]+)(:([0-9]+))?((/[a-zA-Z0-9\\-_.]+)*)/?$");
046    
047    private SiteManager _siteManager;
048
049    private PopulationContextHelper _populationContextHelper;
050    
051    @Override
052    public void service(ServiceManager sManager) throws ServiceException
053    {
054        super.service(sManager);
055        _siteManager = (SiteManager) sManager.lookup(SiteManager.ROLE);
056        _populationContextHelper = (PopulationContextHelper) manager.lookup(PopulationContextHelper.ROLE);
057    }
058    
059    @Override
060    public void generate() throws IOException, SAXException, ProcessingException
061    {
062        AmetysObjectIterable<Site> sites = _siteManager.getRootSites();
063        
064        contentHandler.startDocument();
065        XMLUtils.startElement(contentHandler, "sites");
066        
067        for (Site site : sites)
068        {
069            _saxSite(site);
070        }
071        
072        XMLUtils.endElement(contentHandler, "sites");
073        contentHandler.endDocument();
074    }
075    
076    private void _saxSite(Site site)
077    {
078        try
079        {
080            // check all urls BEFORE starting sax
081            for (String url : site.getUrlAliases())
082            {
083                Matcher matcher = URL_PATTERN.matcher(url);
084                
085                if (!matcher.matches())
086                {
087                    getLogger().error("The site url '" + url + "' is not valid for site " + site.getName());
088                    return;
089                }
090            }
091            
092            // Start sax
093            AttributesImpl atts = new AttributesImpl();
094            atts.addCDATAAttribute("name", site.getName());
095            XMLUtils.startElement(contentHandler, "site", atts);
096            
097            // Sax populations
098            XMLUtils.startElement(contentHandler, "populations");
099            
100            List<String> contexts = new ArrayList<>();
101            contexts.add("/sites/" + site.getName());
102            contexts.add("/sites-fo/" + site.getName());
103            
104            Set<String> userPopulationsOnContext = _populationContextHelper.getUserPopulationsOnContexts(contexts, false, false);
105            for (String populationId : userPopulationsOnContext)
106            {
107                XMLUtils.createElement(contentHandler, "population", populationId);
108            }
109            XMLUtils.endElement(contentHandler, "populations");
110            
111            // Sax urls
112            for (String url : site.getUrlAliases())
113            {
114                Matcher matcher = URL_PATTERN.matcher(url);
115                
116                matcher.matches();
117                
118                String protocol = matcher.group(1);
119                String serverName = matcher.group(2);
120                String port = matcher.group(4);
121                String path = matcher.group(5);
122            
123                port = (port != null) ? port : ("https".equals(protocol) ? "443" : "80");
124                path = (path != null) ? path : "";
125                
126                atts = new AttributesImpl();
127                atts.addCDATAAttribute("serverName", serverName);
128                atts.addCDATAAttribute("serverPort", port);
129                atts.addCDATAAttribute("serverPath", path);
130                
131                XMLUtils.createElement(contentHandler, "url", atts);
132            }
133            
134            // Sax languages
135            XMLUtils.startElement(contentHandler, "languages");
136            for (Sitemap sitemap : site.getSitemaps())
137            {
138                XMLUtils.createElement(contentHandler, sitemap.getName());
139            }
140            XMLUtils.endElement(contentHandler, "languages");
141            
142            // Get children site
143            AmetysObjectIterable<Site> childrenSites = site.getChildrenSites();
144            for (Site child : childrenSites)
145            {
146                _saxSite(child);
147            }
148            
149            XMLUtils.endElement(contentHandler, "site");
150        }
151        catch (Exception ex)
152        {
153            getLogger().warn("An error occured while retrieving informations for site: " + site.getName(), ex);
154        }
155    }
156}