001/*
002 *  Copyright 2011 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.webcontentio.docx;
017
018import java.io.IOException;
019import java.io.InputStream;
020import java.time.ZonedDateTime;
021import java.util.Map;
022
023import org.apache.avalon.framework.context.ContextException;
024import org.apache.avalon.framework.context.Contextualizable;
025import org.apache.avalon.framework.parameters.Parameters;
026import org.apache.cocoon.Constants;
027import org.apache.cocoon.ProcessingException;
028import org.apache.cocoon.environment.Context;
029import org.apache.cocoon.environment.ObjectModelHelper;
030import org.apache.cocoon.environment.SourceResolver;
031import org.apache.cocoon.transformation.AbstractTransformer;
032import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
033import org.apache.commons.compress.archivers.zip.ZipFile;
034import org.xml.sax.Attributes;
035import org.xml.sax.SAXException;
036import org.xml.sax.helpers.AttributesImpl;
037
038import org.ametys.cms.data.NamedResource;
039import org.ametys.cms.data.RichText;
040import org.ametys.cms.repository.Content;
041import org.ametys.cms.repository.ModifiableContent;
042
043/**
044 * Cocoon Transformer for getting images from the docx file after transformation to docbook.
045 */
046public class DocxImagesTransformer extends AbstractTransformer implements Contextualizable
047{
048    private ZipFile _zipFile;
049    private Content _content;
050    private Context _context;
051    
052    @Override
053    public void contextualize(org.apache.avalon.framework.context.Context context) throws ContextException
054    {
055        _context = (Context) context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
056    }
057    
058    @Override
059    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException
060    {
061        @SuppressWarnings("unchecked")
062        Map<String, Object> parentContext = (Map<String, Object>) objectModel.get(ObjectModelHelper.PARENT_CONTEXT);
063        _zipFile = (ZipFile) parentContext.get("zipFile");
064        _content = (Content) parentContext.get("content");
065    }
066    
067    @Override
068    public void startElement(String uri, String localName, String raw, Attributes atts) throws SAXException
069    {
070        if ("imagedata".equals(localName) && "local".equals(atts.getValue("type")))
071        {
072            String fileName = atts.getValue("filename");
073            String fileRef = atts.getValue("fileref");
074            
075            AttributesImpl atts2 = new AttributesImpl();
076            for (int i = 0; i < atts.getLength(); i++)
077            {
078                String name = atts.getQName(i);
079                
080                if (!"filename".equals(name) && !"fileref".equals(name))
081                {
082                    atts2.addAttribute(atts.getURI(i), atts.getLocalName(i), name, atts.getType(i), atts.getValue(i));
083                }
084            }
085            
086            atts2.addAttribute("", "fileref", "fileref", "CDATA", fileName);
087            
088            ZipArchiveEntry entry = _zipFile.getEntry("word/" + fileRef);
089            try (InputStream is = _zipFile.getInputStream(entry))
090            {
091                NamedResource file = new NamedResource();
092                file.setLastModificationDate(ZonedDateTime.now());
093                file.setInputStream(is);
094                
095                String mimeType = _context.getMimeType(fileName);
096                file.setMimeType(mimeType != null ? mimeType : "application/unknown");
097                
098                
099                RichText richText = _content.getValue("content");
100                if (richText == null)
101                {
102                    richText = new RichText();
103                }
104                
105                richText.addAttachment(file);
106                
107                ((ModifiableContent) _content).setValue("content", richText);
108            }
109            catch (IOException e)
110            {
111                throw new SAXException("Unable to get image in the docx file", e);
112            }
113            
114            super.startElement(uri, localName, raw, atts2);
115            return;
116        }
117
118        super.startElement(uri, localName, raw, atts);
119    }
120    
121    @Override
122    public void recycle()
123    {
124        super.recycle();
125        
126        _zipFile = null;
127        _content = null;
128    }
129}