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.cms.content;
018
019import java.io.IOException;
020import java.util.ArrayList;
021import java.util.List;
022import java.util.Map;
023
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.cocoon.ProcessingException;
027import org.apache.cocoon.environment.ObjectModelHelper;
028import org.apache.cocoon.generation.ServiceableGenerator;
029import org.apache.cocoon.xml.AttributesImpl;
030import org.apache.cocoon.xml.XMLUtils;
031import org.apache.commons.lang3.StringUtils;
032import org.xml.sax.SAXException;
033
034import org.ametys.cms.content.references.OutgoingReferences;
035import org.ametys.cms.contenttype.ContentTypesHelper;
036import org.ametys.cms.repository.Content;
037import org.ametys.cms.transformation.ConsistencyChecker;
038import org.ametys.cms.transformation.ConsistencyChecker.CHECK;
039import org.ametys.plugins.repository.AmetysObjectResolver;
040import org.ametys.plugins.repository.UnknownAmetysObjectException;
041import org.ametys.plugins.repository.data.type.ModelItemTypeConstants;
042import org.ametys.runtime.i18n.I18nizableText;
043import org.ametys.runtime.model.ModelHelper;
044import org.ametys.runtime.model.ModelItem;
045
046/**
047 * Generates the consistency report for the given content
048 */
049public class ConsistencyGenerator extends ServiceableGenerator
050{
051    /** Repository content */
052    protected AmetysObjectResolver _resolver;
053    /** The consistency checker */
054    protected ConsistencyChecker _consistencyChecker;
055    /** The content types helper */
056    protected ContentTypesHelper _contentTypesHelper;
057    /** The content helper */
058    protected ContentHelper _contentHelper;
059    
060    @Override
061    public void service(ServiceManager smanager) throws ServiceException
062    {
063        super.service(smanager);
064        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
065        _consistencyChecker = (ConsistencyChecker) smanager.lookup(ConsistencyChecker.ROLE);
066        _contentTypesHelper = (ContentTypesHelper) smanager.lookup(ContentTypesHelper.ROLE);
067        _contentHelper = (ContentHelper) smanager.lookup(ContentHelper.ROLE);
068    }
069
070    @Override
071    public void generate() throws IOException, SAXException, ProcessingException
072    {
073        contentHandler.startDocument();
074        XMLUtils.startElement(contentHandler, "contents");
075        
076        @SuppressWarnings("unchecked")
077        Map<String, Object> jsParameters = (Map<String, Object>) objectModel.get(ObjectModelHelper.PARENT_CONTEXT);
078        @SuppressWarnings("unchecked")
079        List<String> contentsId = (List<String>) jsParameters.get("contentsId");
080        for (String contentId : contentsId)
081        {
082            try
083            {
084                Content content = _resolver.resolveById(contentId);
085                
086                AttributesImpl attrs = new AttributesImpl();
087                attrs.addCDATAAttribute("id", content.getId());
088                attrs.addCDATAAttribute("title", _contentHelper.getTitle(content));
089                attrs.addCDATAAttribute("name", content.getName());
090                attrs.addCDATAAttribute("path", content.getPath());
091                attrs.addCDATAAttribute("type", StringUtils.join(content.getTypes(), ','));
092                if (content.getLanguage() != null)
093                {
094                    attrs.addCDATAAttribute("lang", content.getLanguage());
095                }
096
097                XMLUtils.startElement(contentHandler, "content", attrs);
098                
099                List<ModelItem> modelItemsToSax = new ArrayList<>();
100                Map<String, OutgoingReferences> referencesByPath = content.getOutgoingReferences();
101                
102                for (String dataPath : referencesByPath.keySet())
103                {
104                    List<ModelItem> modelItemPath = _contentTypesHelper.getModelItemPath(dataPath, content);
105                    
106                    // Add these model items to the set of model items to SAX.
107                    modelItemsToSax.addAll(modelItemPath);
108                    
109                    // SAX'ing consistency info
110                    String definitionPath = ModelHelper.getDefinitionPathFromDataPath(dataPath);
111                    OutgoingReferences references = referencesByPath.get(dataPath);
112                    for (String referenceType : references.keySet())
113                    {
114                        for (String referenceValue : references.get(referenceType))
115                        {
116                            attrs.clear();
117                            attrs.addCDATAAttribute("type", referenceType);
118                            attrs.addCDATAAttribute("element", referenceValue);
119                            attrs.addCDATAAttribute("path", definitionPath);
120                            I18nizableText label = _consistencyChecker.getLabel(referenceType, referenceValue, content.getId(), dataPath);
121                            
122                            CHECK check = CHECK.SERVER_ERROR;
123                            try
124                            {
125                                check = _consistencyChecker.checkConsistency(referenceType, referenceValue, content.getId(), dataPath, false);
126                            }
127                            catch (Exception e)
128                            {
129                                // Ignore, consider it a failure.
130                            }
131                            
132                            switch (check)
133                            {
134                                case SUCCESS:
135                                    XMLUtils.startElement(contentHandler, "success", attrs);
136                                    label.toSAX(contentHandler);
137                                    XMLUtils.endElement(contentHandler, "success");
138                                    break;
139                                case UNKNOWN:
140                                    XMLUtils.startElement(contentHandler, "unknown", attrs);
141                                    label.toSAX(contentHandler);
142                                    XMLUtils.endElement(contentHandler, "unknown");
143                                    break;
144                                case UNAUTHORIZED:
145                                    XMLUtils.startElement(contentHandler, "unauthorized", attrs);
146                                    label.toSAX(contentHandler);
147                                    XMLUtils.endElement(contentHandler, "unauthorized");
148                                    break;
149                                case NOT_FOUND:
150                                    XMLUtils.startElement(contentHandler, "not-found", attrs);
151                                    label.toSAX(contentHandler);
152                                    XMLUtils.endElement(contentHandler, "not-found");
153                                    break;
154                                case SERVER_ERROR:
155                                default:
156                                    XMLUtils.startElement(contentHandler, "server-error", attrs);
157                                    label.toSAX(contentHandler);
158                                    XMLUtils.endElement(contentHandler, "server-error");
159                                    break;
160                            }
161                        }
162                    }
163                }
164                
165                // SAX model items used for this content
166                for (ModelItem modelItem : modelItemsToSax)
167                {
168                    attrs.clear();
169                    attrs.addCDATAAttribute("path", modelItem.getPath());
170                    attrs.addCDATAAttribute("is-repeater", Boolean.toString(ModelItemTypeConstants.REPEATER_TYPE_ID.equals(modelItem.getType().getId())));
171                    XMLUtils.startElement(contentHandler, "metadata-definition", attrs);
172                    modelItem.getLabel().toSAX(contentHandler);
173                    XMLUtils.endElement(contentHandler, "metadata-definition");
174                }
175                
176                XMLUtils.endElement(contentHandler, "content");
177            }
178            catch (UnknownAmetysObjectException e)
179            {
180                getLogger().warn("Can not check consistency of non existing content '" + contentId + "'");
181            }
182        }
183        
184        XMLUtils.endElement(contentHandler, "contents");
185        contentHandler.endDocument();
186    }
187}