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.util.Date;
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.repository.Content;
039import org.ametys.plugins.repository.metadata.ModifiableCompositeMetadata;
040import org.ametys.plugins.repository.metadata.ModifiableResource;
041
042/**
043 * Cocoon Transformer for getting images from the docx file after transformation to docbook.
044 */
045public class DocxImagesTransformer extends AbstractTransformer implements Contextualizable
046{
047    private ZipFile _zipFile;
048    private Content _content;
049    private Context _context;
050    
051    @Override
052    public void contextualize(org.apache.avalon.framework.context.Context context) throws ContextException
053    {
054        _context = (Context) context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
055    }
056    
057    @Override
058    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException
059    {
060        @SuppressWarnings("unchecked")
061        Map<String, Object> parentContext = (Map<String, Object>) objectModel.get(ObjectModelHelper.PARENT_CONTEXT);
062        _zipFile = (ZipFile) parentContext.get("zipFile");
063        _content = (Content) parentContext.get("content");
064    }
065    
066    @Override
067    public void startElement(String uri, String localName, String raw, Attributes atts) throws SAXException
068    {
069        if ("imagedata".equals(localName) && "local".equals(atts.getValue("type")))
070        {
071            String fileName = atts.getValue("filename");
072            String fileRef = atts.getValue("fileref");
073            
074            AttributesImpl atts2 = new AttributesImpl();
075            for (int i = 0; i < atts.getLength(); i++)
076            {
077                String name = atts.getQName(i);
078                
079                if (!"filename".equals(name) && !"fileref".equals(name))
080                {
081                    atts2.addAttribute(atts.getURI(i), atts.getLocalName(i), name, atts.getType(i), atts.getValue(i));
082                }
083            }
084            
085            atts2.addAttribute("", "fileref", "fileref", "CDATA", _content.getId() + "@content;" + fileName);
086            
087            ModifiableResource file = ((ModifiableCompositeMetadata) _content.getMetadataHolder()).getRichText("content", true).getAdditionalDataFolder().addFile(fileName).getResource();
088            
089            ZipArchiveEntry entry = _zipFile.getEntry("word/" + fileRef);
090            try (InputStream is = _zipFile.getInputStream(entry))
091            {
092                file.setLastModified(new Date());
093                file.setInputStream(is);
094                
095                String mimeType = _context.getMimeType(fileName);
096                file.setMimeType(mimeType != null ? mimeType : "application/unknown");
097            }
098            catch (IOException e)
099            {
100                throw new SAXException("Unable to get image in the docx file", e);
101            }
102            
103            super.startElement(uri, localName, raw, atts2);
104            return;
105        }
106
107        super.startElement(uri, localName, raw, atts);
108    }
109    
110    @Override
111    public void recycle()
112    {
113        super.recycle();
114        
115        _zipFile = null;
116        _content = null;
117    }
118}