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.cms.content;
017
018import java.io.IOException;
019import java.io.InputStream;
020import java.io.Serializable;
021import java.net.URLDecoder;
022import java.util.Arrays;
023import java.util.Iterator;
024import java.util.List;
025import java.util.Map;
026
027import org.apache.avalon.framework.parameters.ParameterException;
028import org.apache.avalon.framework.parameters.Parameters;
029import org.apache.cocoon.ProcessingException;
030import org.apache.cocoon.caching.CacheableProcessingComponent;
031import org.apache.cocoon.environment.ObjectModelHelper;
032import org.apache.cocoon.environment.Request;
033import org.apache.cocoon.environment.SourceResolver;
034import org.apache.excalibur.source.SourceValidity;
035import org.apache.excalibur.source.impl.validity.TimeStampValidity;
036import org.xml.sax.SAXException;
037
038import org.ametys.cms.repository.Content;
039import org.ametys.core.util.cocoon.AbstractResourceReader;
040import org.ametys.plugins.repository.metadata.CompositeMetadata;
041import org.ametys.plugins.repository.metadata.File;
042import org.ametys.plugins.repository.metadata.Folder;
043import org.ametys.plugins.repository.metadata.RichText;
044
045/**
046 * Reader for binary or file metadata.
047 */
048public class ContentFileReader extends AbstractResourceReader implements CacheableProcessingComponent
049{
050    private Content _content;
051    private File _file;
052    
053    private String _path;
054    
055    @Override
056    public void doSetup(SourceResolver res, Map objModel, String src, Parameters par) throws ProcessingException, IOException
057    {
058        Request request = ObjectModelHelper.getRequest(objectModel);
059        _content = (Content) request.getAttribute(Content.class.getName());
060        
061        String metadataName = parameters.getParameter("metadata", null);
062        RichText richText = _getMeta(_content.getMetadataHolder(), metadataName);
063        
064        Folder folder = richText.getAdditionalDataFolder();
065        
066        try
067        {
068            _path = parameters.getParameter("path");
069        }
070        catch (ParameterException e)
071        {
072            throw new ProcessingException("The path parameter is mandatory for reading binary metadata.", e);
073        }
074        
075        List<String> pathElements = Arrays.asList(_path.split("/"));
076        
077        Iterator<String> it = pathElements.iterator();
078        
079        while (it.hasNext())
080        {
081            String pathElement = it.next();
082            pathElement = URLDecoder.decode(pathElement, "utf-8");
083            
084            if (it.hasNext())
085            {
086                // not the last segment : it is a composite
087                folder = folder.getFolder(pathElement);
088            }
089            else
090            {
091                File file = folder.getFile(pathElement);
092                _file = file;
093            }
094        }
095    }
096    
097    @Override
098    public Serializable getKey()
099    {
100        return _path + getKeySuffix();
101    }
102
103    @Override
104    public SourceValidity getValidity()
105    {
106        return new TimeStampValidity(getLastModified());
107    }
108    
109    @Override
110    public long getLastModified()
111    {
112        if (_content != null)
113        {
114            return _content.getLastModified().getTime();
115        }
116        
117        return super.getLastModified();
118    }
119    
120    @Override
121    public String getMimeType()
122    {
123        if (_file != null)
124        {
125            return _file.getResource().getMimeType();
126        }
127
128        return super.getMimeType();
129    }
130    
131    @Override
132    protected InputStream getInputStream()
133    {
134        return _file.getResource().getInputStream();
135    }
136    
137    @Override
138    protected String getFilename()
139    {
140        return _file.getName();
141    }
142    
143    @Override
144    protected String getEncodedFilename()
145    {
146        return null;
147    }
148    
149    @Override
150    protected long getLength()
151    {
152        return _file.getResource().getLength();
153    }
154    
155    /** 
156     * Get the rich text meta
157     * @param meta The composite meta
158     * @param metadataName The metadata name (with /)
159     * @return The rich text meta
160     */
161    protected RichText _getMeta(CompositeMetadata meta, String metadataName)
162    {
163        int pos = metadataName.indexOf("/");
164        if (pos == -1)
165        {
166            return meta.getRichText(metadataName);
167        }
168        return _getMeta(meta.getCompositeMetadata(metadataName.substring(0, pos)), metadataName.substring(pos + 1));
169    }
170    
171    @Override
172    public void recycle()
173    {
174        super.recycle();
175        
176        _file = null;
177        _content = null;
178    }
179}