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