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 */
016package org.ametys.plugins.explorer.resources.generators;
017
018import java.io.IOException;
019
020import org.apache.avalon.framework.service.ServiceException;
021import org.apache.avalon.framework.service.ServiceManager;
022import org.apache.cocoon.ProcessingException;
023import org.apache.cocoon.environment.ObjectModelHelper;
024import org.apache.cocoon.environment.Request;
025import org.apache.cocoon.generation.ServiceableGenerator;
026import org.apache.cocoon.serialization.ZipArchiveSerializer;
027import org.apache.cocoon.xml.AttributesImpl;
028import org.apache.cocoon.xml.XMLUtils;
029import org.xml.sax.SAXException;
030
031import org.ametys.core.util.URIUtils;
032import org.ametys.plugins.explorer.ExplorerNode;
033import org.ametys.plugins.explorer.resources.Resource;
034import org.ametys.plugins.explorer.resources.ResourceCollection;
035import org.ametys.plugins.repository.AmetysObject;
036import org.ametys.plugins.repository.AmetysObjectIterable;
037import org.ametys.plugins.repository.AmetysObjectResolver;
038
039/**
040 * Generates a ZIP archive for the selected resources
041 *
042 */
043public class ZipArchiveGenerator extends ServiceableGenerator
044{
045    private AmetysObjectResolver _resolver;
046
047    @Override
048    public void service(ServiceManager smanager) throws ServiceException
049    {
050        super.service(smanager);
051        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
052    }
053    
054    @Override
055    public void generate() throws IOException, SAXException, ProcessingException
056    {
057        Request request = ObjectModelHelper.getRequest(objectModel);
058        
059        String id = request.getParameter("id");
060        String[] files = request.getParameterValues("file");
061        boolean ignoreFolder = parameters.getParameterAsBoolean("ignoreFolder", false);
062        
063        contentHandler.startDocument();
064        contentHandler.startPrefixMapping("zip", ZipArchiveSerializer.ZIP_NAMESPACE);
065        XMLUtils.startElement(contentHandler, ZipArchiveSerializer.ZIP_NAMESPACE, "archive");
066
067        if (files != null)
068        {
069            // Export the selected files (should have same parent)
070            for (String fileId : files)
071            {
072                AmetysObject ao = _resolver.resolveById(fileId);
073               
074                if (!ignoreFolder && ao instanceof ResourceCollection)
075                {
076                    _saxResourceCollectionEntry ((ResourceCollection) ao, _getParentPath(ao), ignoreFolder);
077                }
078                else if (ao instanceof Resource)
079                {
080                    _saxResourceEntry ((Resource) ao, _getParentPath(ao));
081                }
082            }
083        }
084        else
085        {
086            ResourceCollection collection = _resolver.resolveById(id);
087            _saxResourceCollectionEntry (collection, _getParentPath(collection), ignoreFolder);
088        }
089        
090        XMLUtils.endElement(contentHandler, ZipArchiveSerializer.ZIP_NAMESPACE, "archive");
091        contentHandler.endPrefixMapping("zip");
092        contentHandler.endDocument();
093    }
094    
095    private String _getParentPath(AmetysObject ao)
096    {
097        String parentPath = "";
098        if (ao.getParent() instanceof ExplorerNode)
099        {
100            parentPath = ((ExplorerNode) ao.getParent()).getExplorerPath();
101        }
102        
103        return parentPath;
104    }
105    
106    private void _saxResourceCollectionEntry (ResourceCollection collection, String fromPath, boolean ignoreFolder) throws SAXException
107    {
108        AmetysObjectIterable<AmetysObject> children = collection.getChildren();
109
110        for (AmetysObject child : children)
111        {
112            if (child instanceof Resource)
113            {
114                Resource resource = (Resource) child;
115                _saxResourceEntry(resource, fromPath);
116            }
117            else if (!ignoreFolder && child instanceof ResourceCollection)
118            {
119                _saxResourceCollectionEntry((ResourceCollection) child, fromPath, ignoreFolder);
120            }
121        }
122    }
123    
124    private void _saxResourceEntry(Resource resource, String fromPath) throws SAXException
125    {
126        AttributesImpl attrs = new AttributesImpl();
127        attrs.addCDATAAttribute("name", resource.getResourcePath().substring(fromPath.length() + 1));
128        attrs.addCDATAAttribute("src", "cocoon:/resource?id=" + URIUtils.encodeParameter(resource.getId()));
129        XMLUtils.startElement(contentHandler, ZipArchiveSerializer.ZIP_NAMESPACE, "entry", attrs);
130        XMLUtils.endElement(contentHandler, ZipArchiveSerializer.ZIP_NAMESPACE, "entry");
131    }
132
133}