001/*
002 *  Copyright 2019 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.odf.schedulable;
017
018import java.io.IOException;
019import java.util.Date;
020import java.util.Set;
021
022import org.apache.avalon.framework.service.ServiceException;
023import org.apache.avalon.framework.service.ServiceManager;
024import org.apache.cocoon.ProcessingException;
025import org.apache.cocoon.generation.ServiceableGenerator;
026import org.apache.cocoon.xml.AttributesImpl;
027import org.apache.cocoon.xml.XMLUtils;
028import org.apache.commons.lang3.StringUtils;
029import org.xml.sax.SAXException;
030
031import org.ametys.cms.contenttype.ContentTypesHelper;
032import org.ametys.cms.repository.Content;
033import org.ametys.cms.repository.ContentQueryHelper;
034import org.ametys.cms.repository.ContentTypeExpression;
035import org.ametys.cms.repository.WorkflowAwareContent;
036import org.ametys.core.user.UserIdentity;
037import org.ametys.core.util.DateUtils;
038import org.ametys.odf.ProgramItem;
039import org.ametys.odf.catalog.Catalog;
040import org.ametys.odf.catalog.CatalogsManager;
041import org.ametys.odf.program.ProgramFactory;
042import org.ametys.odf.workflow.ODFWorkflowHelper;
043import org.ametys.plugins.core.user.UserHelper;
044import org.ametys.plugins.repository.AmetysObjectIterable;
045import org.ametys.plugins.repository.AmetysObjectResolver;
046import org.ametys.plugins.repository.query.expression.Expression;
047import org.ametys.plugins.repository.query.expression.Expression.Operator;
048
049/**
050 * Generate XML report for global validation on all programs.
051 */
052public class GlobalValidationReportGenerator extends ServiceableGenerator
053{
054    private ODFWorkflowHelper _odfWorkflowHelper;
055    private AmetysObjectResolver _resolver;
056    private ContentTypesHelper _cTypesHelper;
057    private CatalogsManager _catalogManager;
058    private UserHelper _userHelper;
059
060    @Override
061    public void service(ServiceManager smanager) throws ServiceException
062    {
063        super.service(smanager);
064        _odfWorkflowHelper = (ODFWorkflowHelper) smanager.lookup(ODFWorkflowHelper.ROLE);
065        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
066        _cTypesHelper = (ContentTypesHelper) smanager.lookup(ContentTypesHelper.ROLE);
067        _catalogManager = (CatalogsManager) smanager.lookup(CatalogsManager.ROLE);
068        _userHelper = (UserHelper) smanager.lookup(UserHelper.ROLE);
069    }
070    
071    public void generate() throws IOException, SAXException, ProcessingException
072    {
073        contentHandler.startDocument();
074        
075        AttributesImpl atts = new AttributesImpl();
076        
077        atts.addCDATAAttribute("date", DateUtils.dateToString(new Date()));
078        XMLUtils.startElement(contentHandler, "programs", atts);
079        
080        try (AmetysObjectIterable<Content> programs = _getPrograms())
081        {
082            for (Content program : programs)
083            {
084                Set<Content> invalidatedContents = _odfWorkflowHelper.getInvalidatedContents((WorkflowAwareContent) program);
085                if (!invalidatedContents.isEmpty())
086                {
087                    _saxGlobalValidationStatus(program, invalidatedContents);
088                }
089            }
090        }
091        
092        XMLUtils.endElement(contentHandler, "programs");
093        
094        contentHandler.endDocument();
095
096    }
097    
098    private AmetysObjectIterable<Content> _getPrograms()
099    {
100        Expression expression = new ContentTypeExpression(Operator.EQ, ProgramFactory.PROGRAM_CONTENT_TYPE);
101        
102        String query = ContentQueryHelper.getContentXPathQuery(expression);
103        
104        return _resolver.query(query);
105    }
106    
107    private void _saxGlobalValidationStatus(Content content, Set<Content> invalidatedContents) throws SAXException
108    {
109        AttributesImpl atts = new AttributesImpl();
110        atts.addCDATAAttribute("id", content.getId());
111        atts.addCDATAAttribute("title", content.getTitle(null));
112        
113        String smallIcon = _cTypesHelper.getSmallIcon(content);
114        if (StringUtils.isNotEmpty(smallIcon))
115        {
116            atts.addCDATAAttribute("iconSmall", smallIcon);
117        }
118        String iconGlyph = _cTypesHelper.getIconGlyph(content);
119        if (StringUtils.isNotEmpty(iconGlyph))
120        {
121            atts.addCDATAAttribute("iconGlyph", iconGlyph);
122        }
123        
124        atts.addCDATAAttribute("invalidated-contents-count", Integer.toString(invalidatedContents.size()));
125        
126        XMLUtils.startElement(contentHandler, "program", atts);
127        
128        if (content instanceof ProgramItem)
129        {
130            XMLUtils.createElement(contentHandler, "code", ((ProgramItem) content).getCode());
131            
132            String codeCatalog = ((ProgramItem) content).getCatalog();
133            Catalog catalog = _catalogManager.getCatalog(codeCatalog);
134            if (catalog != null)
135            {
136                AttributesImpl catalogAttrs = new AttributesImpl();
137                catalogAttrs.addCDATAAttribute("code", codeCatalog);
138                XMLUtils.createElement(contentHandler, "catalog", catalogAttrs, catalog.getTitle());
139            }
140        }
141        
142        XMLUtils.createElement(contentHandler, "lastModified", DateUtils.zonedDateTimeToString(content.getLastModified()));
143        
144        UserIdentity user = content.getLastContributor();
145        _userHelper.saxUserIdentity(user, contentHandler, "contributor");
146        
147        XMLUtils.startElement(contentHandler, "invalidatedContents");
148        for (Content invalidatedContent : invalidatedContents)
149        {
150            _saxInvalidatedContent(invalidatedContent);
151        }
152        XMLUtils.endElement(contentHandler, "invalidatedContents");
153        
154        XMLUtils.endElement(contentHandler, "program");
155    }
156    
157    private void _saxInvalidatedContent(Content content) throws SAXException
158    {
159        AttributesImpl atts = new AttributesImpl();
160        atts.addCDATAAttribute("id", content.getId());
161        atts.addCDATAAttribute("title", content.getTitle(null));
162        if (content instanceof ProgramItem)
163        {
164            atts.addCDATAAttribute("code", ((ProgramItem) content).getCode());
165        }
166        
167        XMLUtils.createElement(contentHandler, "content", atts);
168    }
169
170}