001/*
002 *  Copyright 2014 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.export.pdf;
017
018import java.io.IOException;
019import java.net.MalformedURLException;
020import java.util.Map;
021
022import org.apache.avalon.framework.parameters.ParameterException;
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.cocoon.ProcessingException;
026import org.apache.cocoon.components.source.impl.SitemapSource;
027import org.apache.cocoon.generation.ServiceableGenerator;
028import org.apache.cocoon.xml.AttributesImpl;
029import org.apache.cocoon.xml.XMLUtils;
030import org.xml.sax.SAXException;
031
032import org.ametys.cms.contenttype.ContentConstants;
033import org.ametys.cms.contenttype.ContentTypeExtensionPoint;
034import org.ametys.cms.contenttype.MetadataDefinition;
035import org.ametys.cms.contenttype.MetadataDefinitionReference;
036import org.ametys.cms.contenttype.MetadataManager;
037import org.ametys.cms.contenttype.MetadataSet;
038import org.ametys.core.util.IgnoreRootHandler;
039import org.ametys.odf.catalog.Catalog;
040import org.ametys.odf.catalog.CatalogsManager;
041import org.ametys.odf.enumeration.OdfReferenceTableHelper;
042import org.ametys.odf.program.Program;
043import org.ametys.odf.program.ProgramFactory;
044import org.ametys.plugins.repository.AmetysObjectIterable;
045import org.ametys.plugins.repository.AmetysObjectResolver;
046import org.ametys.plugins.repository.AmetysRepositoryException;
047import org.ametys.plugins.repository.UnknownAmetysObjectException;
048
049
050/**
051 * Generator producing the SAX events for the catalogue summary 
052 */ 
053public class FOProgramsGenerator extends ServiceableGenerator
054{
055    /** The Ametys object resolver */
056    protected AmetysObjectResolver _ametysObjectResolver;
057    /** The content type extension point */
058    protected ContentTypeExtensionPoint _ctypeEP;
059    /** The metadata manager */
060    protected MetadataManager _metadataManager;
061    /** The ODf enumeration helper */
062    protected OdfReferenceTableHelper _odfTableRefHelper;
063    /** The catalog manager */
064    protected CatalogsManager _catalogManager;
065    
066    @Override
067    public void service(ServiceManager sManager) throws ServiceException
068    {
069        super.service(sManager);
070        _ametysObjectResolver = (AmetysObjectResolver) sManager.lookup(AmetysObjectResolver.ROLE);
071        _ctypeEP = (ContentTypeExtensionPoint) sManager.lookup(ContentTypeExtensionPoint.ROLE);
072        _metadataManager = (MetadataManager) sManager.lookup(MetadataManager.ROLE);
073        _odfTableRefHelper = (OdfReferenceTableHelper) sManager.lookup(OdfReferenceTableHelper.ROLE);
074        _catalogManager = (CatalogsManager) sManager.lookup(CatalogsManager.ROLE);
075    }
076    
077    public void generate() throws IOException, SAXException, ProcessingException
078    {
079        contentHandler.startDocument();
080        XMLUtils.startElement(contentHandler, "programs");
081        
082        Catalog catalog = null;
083        if ("_default".equals(source) && _catalogManager.getCatalogs().size() > 0)
084        {
085            catalog = _catalogManager.getCatalogs().get(0);
086        }
087        else
088        {
089            catalog = _catalogManager.getCatalog(source);
090        }
091        
092        if (catalog == null)
093        {
094            throw new IllegalArgumentException ("Failed to generated PDF of unknown catalog '" + source + "'");
095        }
096        
097        AttributesImpl attrs = new AttributesImpl();
098        attrs.addCDATAAttribute("name", source);
099        XMLUtils.createElement(contentHandler, "catalog", attrs, catalog.getTitle());
100        
101        Map<String, MetadataDefinition> tableRefMetadataDefs = _odfTableRefHelper.getTableRefMetadataDefinition(ProgramFactory.PROGRAM_CONTENT_TYPE);
102        
103        try
104        {
105            _saxPrograms(catalog.getName(), parameters.getParameter("lang"), tableRefMetadataDefs);
106        }
107        catch (ParameterException e)
108        {
109            throw new IllegalArgumentException ("Missing lang parameter", e);
110        }
111        
112        // SAX entries of table references
113        XMLUtils.startElement(contentHandler, "enumerated-metadata");
114        for (MetadataDefinition metaDef : tableRefMetadataDefs.values())
115        {
116            _odfTableRefHelper.saxItems(contentHandler, metaDef);
117        }
118        XMLUtils.endElement(contentHandler, "enumerated-metadata");
119        
120        XMLUtils.endElement(contentHandler, "programs");
121        contentHandler.endDocument();
122    }
123    
124    /**
125     * SAX programs
126     * @param catalog the catalog's name
127     * @param lang the programs' language
128     * @param tableRefMetaDefs The table reference metadata definitions
129     * @throws MalformedURLException if an error occurred
130     * @throws IOException if an error occurred
131     * @throws SAXException if an error occurred
132     */
133    protected void _saxPrograms(String catalog, String lang, Map<String, MetadataDefinition> tableRefMetaDefs) throws MalformedURLException, IOException, SAXException
134    {
135        AmetysObjectIterable<Program> programs = _catalogManager.getPrograms(catalog, lang);
136        
137        for (Program program : programs)
138        {
139            AttributesImpl attrs = new AttributesImpl();
140            attrs.addCDATAAttribute("id", program.getId());
141            attrs.addCDATAAttribute("name", program.getName());
142            attrs.addCDATAAttribute("title", program.getTitle());
143            
144            XMLUtils.startElement(contentHandler, "program", attrs);
145            
146            _saxTableRefMetadataValues (program, tableRefMetaDefs);
147            
148            XMLUtils.startElement(contentHandler, "fo");
149            SitemapSource src = null;      
150            
151            try
152            {
153                String uri = "cocoon://_plugins/odf/_content/" + program.getName() + ".fo";
154                src = (SitemapSource) resolver.resolveURI(uri);
155                src.toSAX(new IgnoreRootHandler(contentHandler));
156            }
157            catch (UnknownAmetysObjectException e)
158            {
159                // The content may be archived
160            }
161            finally
162            {
163                resolver.release(src);
164            }
165            
166            XMLUtils.endElement(contentHandler, "fo");
167            XMLUtils.endElement(contentHandler, "program");
168        }
169    }
170    
171    /**
172     * SAX enumerated values of a metadata 
173     * @param program The program
174     * @param tableRefMetaDefs The table reference metadata definitions
175     * @throws AmetysRepositoryException if an error occurred
176     * @throws SAXException if an error occurred
177     * @throws IOException if an error occurred
178     */
179    protected void _saxTableRefMetadataValues(Program program, Map<String, MetadataDefinition> tableRefMetaDefs) throws AmetysRepositoryException, SAXException, IOException
180    {
181        // Build metadata set
182        MetadataSet tableRefMetadataSet = new MetadataSet();
183        
184        for (String metadataPath : tableRefMetaDefs.keySet())
185        {
186            String[] pathSegments = org.apache.commons.lang.StringUtils.split(metadataPath, ContentConstants.METADATA_PATH_SEPARATOR);
187            
188            MetadataDefinitionReference metadataDefRef = new MetadataDefinitionReference(pathSegments[0]);
189            tableRefMetadataSet.addElement(metadataDefRef);
190            
191            for (int i = 1; i < pathSegments.length; i++)
192            {
193                MetadataDefinitionReference subMetadataDefRef = new MetadataDefinitionReference(pathSegments[i]);
194                metadataDefRef.addElement(subMetadataDefRef);
195                
196                metadataDefRef = subMetadataDefRef;
197            }
198        }
199        
200        XMLUtils.startElement(contentHandler, "metadata");
201        _metadataManager.saxMetadata(contentHandler, program, tableRefMetadataSet, null);
202        XMLUtils.endElement(contentHandler, "metadata");
203    }
204}