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.userdirectory.generator;
017
018import java.io.IOException;
019import java.util.Optional;
020
021import org.apache.avalon.framework.service.ServiceException;
022import org.apache.avalon.framework.service.ServiceManager;
023import org.apache.cocoon.ProcessingException;
024import org.apache.cocoon.components.source.impl.SitemapSource;
025import org.apache.cocoon.xml.AttributesImpl;
026import org.apache.cocoon.xml.XMLUtils;
027import org.apache.commons.lang.StringUtils;
028import org.apache.excalibur.source.SourceResolver;
029import org.xml.sax.SAXException;
030
031import org.ametys.cms.data.ContentValue;
032import org.ametys.cms.repository.Content;
033import org.ametys.core.util.DateUtils;
034import org.ametys.core.util.IgnoreRootHandler;
035import org.ametys.plugins.repository.AmetysObjectResolver;
036import org.ametys.plugins.repository.UnknownAmetysObjectException;
037import org.ametys.plugins.repository.data.holder.group.impl.ModelAwareRepeater;
038import org.ametys.plugins.repository.data.holder.group.impl.ModelAwareRepeaterEntry;
039import org.ametys.plugins.userdirectory.OrganisationChartPageHandler;
040import org.ametys.web.content.ContentGenerator;
041
042/**
043 * OrgUnit Generator
044 */
045public class OrgUnitGenerator extends ContentGenerator
046{
047    /** The ametys object resolver */
048    protected AmetysObjectResolver _resolver;
049    
050    /** The source resolver */
051    protected SourceResolver _srcResolver;
052    
053    /** The organization chart page handler */
054    protected OrganisationChartPageHandler _organizationChartPageHandler;
055    
056    @Override
057    public void service(ServiceManager serviceManager) throws ServiceException
058    {
059        super.service(serviceManager);
060        _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE);
061        _srcResolver = (SourceResolver) serviceManager.lookup(SourceResolver.ROLE);
062        _organizationChartPageHandler = (OrganisationChartPageHandler) serviceManager.lookup(OrganisationChartPageHandler.ROLE);
063    }
064    
065    @Override
066    protected void _saxOtherData(Content content) throws SAXException, ProcessingException
067    {
068        super._saxOtherData(content);
069        
070        String viewName = parameters.getParameter("viewName", "main");
071        if ("main".equals(viewName))
072        {
073            // Sax users and child orgunits only for view "main"
074            _saxUsers(content);
075            _saxChildOrgUnits(content);
076        }
077    }
078    
079    /**
080     * Sax child orgUnits from the orgUnit content
081     * @param content the content
082     * @throws SAXException if an error occurred
083     */
084    protected void _saxChildOrgUnits(Content content) throws SAXException
085    {
086        XMLUtils.startElement(contentHandler, "orgUnits");
087        for (Content childOrgUnit : _organizationChartPageHandler.getChildContents(content))
088        {
089            saxOrgUnit(childOrgUnit, "link");
090        }
091        XMLUtils.endElement(contentHandler, "orgUnits");
092    }
093    
094    /**
095     * SAX a orgUnit content
096     * @param orgUnit the orgUnit to sax.
097     * @param viewName the view name
098     * @throws SAXException if an error occurs
099     */
100    protected void saxOrgUnit(Content orgUnit, String viewName) throws SAXException
101    {
102        try
103        {
104            AttributesImpl atts = new AttributesImpl();
105            atts.addCDATAAttribute("metadataSetName", viewName);
106            XMLUtils.startElement(contentHandler, "orgUnit", atts);
107            saxContent(orgUnit, viewName);
108            XMLUtils.endElement(contentHandler, "orgUnit");
109        }
110        catch (IOException e)
111        {
112            throw new SAXException(e);
113        }
114    }
115    
116    /**
117     * Sax users from the orgUnit content
118     * @param content the content
119     * @throws SAXException if an error occurred
120     */
121    protected void _saxUsers(Content content) throws SAXException
122    {
123        XMLUtils.startElement(contentHandler, "users");
124        
125        if (content.hasValue("users"))
126        {
127            ModelAwareRepeater users = content.getRepeater("users");
128            for (ModelAwareRepeaterEntry entry: users.getEntries())
129            {
130                if (entry.hasValue("user"))
131                {
132                    ContentValue userValue = entry.getValue("user");
133                    Optional<? extends Content> optionalUser = userValue.getContentIfExists();
134                    
135                    if (optionalUser.isPresent())
136                    {
137                        Content user = optionalUser.get();
138                        String role = entry.getValue("role");
139                        saxUser(user, role, "abstract");
140                        saxUser(user, role, "link");
141                    }
142                    else
143                    {
144                        getLogger().error("Can't find the user from id : " + userValue.getContentId());
145                    }
146                }
147            }
148        }
149        
150        XMLUtils.endElement(contentHandler, "users");
151    }
152    
153    /**
154     * SAX a user content
155     * @param user the user.
156     * @param role the user role
157     * @param viewName the view name
158     * @throws SAXException if an error occurs
159     */
160    protected void saxUser(Content user, String role, String viewName) throws SAXException
161    {
162        try
163        {
164            AttributesImpl atts = new AttributesImpl();
165            atts.addCDATAAttribute("metadataSetName", viewName);
166            if (StringUtils.isNotBlank(role))
167            {
168                atts.addCDATAAttribute("role", role);
169            }
170
171            XMLUtils.startElement(contentHandler, "user", atts);
172            saxContent(user, viewName);
173            XMLUtils.endElement(contentHandler, "user");
174        }
175        catch (IOException e)
176        {
177            throw new SAXException(e);
178        }
179    }
180    
181    /**
182     * SAX the HTML content of a {@link Content}
183     * @param content the content
184     * @param viewName the view name
185     * @throws SAXException If an error occurred saxing the content
186     * @throws IOException If an error occurred resolving the content
187     */
188    protected void saxContent (Content content, String viewName) throws SAXException, IOException
189    {
190        String format = parameters.getParameter("output-format", "html");
191        if (StringUtils.isEmpty(format))
192        {
193            format = "html";
194        }
195        
196        saxContent(content, viewName, format);
197    }
198    
199    /**
200     * SAX a {@link Content} to given format
201     * @param content the content
202     * @param viewName the view name
203     * @param format the output format
204     * @throws SAXException If an error occurred saxing the content
205     * @throws IOException If an error occurred resolving the content
206     */
207    protected void saxContent (Content content, String viewName, String format) throws SAXException, IOException
208    {
209        SitemapSource src = null;      
210        try
211        {
212            String uri = "cocoon://_content." + format + "?contentId=" + content.getId() + "&viewName=" + viewName + "&output-format=" + format;
213            src = (SitemapSource) _srcResolver.resolveURI(uri);
214            
215            AttributesImpl attrs = new AttributesImpl();
216            attrs.addCDATAAttribute("id", content.getId());
217            attrs.addCDATAAttribute("name", content.getName());
218            attrs.addCDATAAttribute("title", content.getTitle());
219            attrs.addCDATAAttribute("lastModifiedAt", DateUtils.dateToString(content.getLastModified()));
220            
221            XMLUtils.startElement(contentHandler, "content", attrs);
222            src.toSAX(new IgnoreRootHandler(contentHandler));
223            XMLUtils.endElement(contentHandler, "content");
224        }
225        catch (UnknownAmetysObjectException e)
226        {
227            // The content may be archived
228        }
229        finally
230        {
231            _srcResolver.release(src);
232        }
233    }
234}