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.plugins.flipbook;
017
018import java.io.InputStream;
019import java.util.Arrays;
020import java.util.Iterator;
021import java.util.List;
022
023import org.apache.commons.codec.digest.DigestUtils;
024import org.apache.tika.io.IOUtils;
025
026import org.ametys.cms.data.Binary;
027import org.ametys.cms.repository.Content;
028import org.ametys.core.util.FilenameUtils;
029import org.ametys.plugins.repository.data.holder.ModelAwareDataHolder;
030import org.ametys.plugins.repository.data.holder.group.impl.ModelAwareRepeater;
031import org.ametys.plugins.repository.data.type.ModelItemTypeConstants;
032import org.ametys.runtime.model.ModelItem;
033
034/**
035 * Implementation of a {@link AbstractConvertDocument2ImagesComponent} for a binary metadata
036 */
037public class ConvertMetadata2ImagesComponent extends AbstractConvertDocument2ImagesComponent
038{
039    /** Avalon ROLE. */
040    public static final String ROLE = ConvertMetadata2ImagesComponent.class.getName();
041    
042    /**
043     * Put the file in cache
044     * @param content the content
045     * @param metadataPath the path of the metadata
046     * @param siteName the name of the site
047     * @return The absolute cache path
048     * @throws Exception if an error occurs while caching the file
049     */
050    public String doCache(Content content, String metadataPath, String siteName) throws Exception
051    {
052        InputStream is = null;
053        InputStream is2 = null;
054        Binary binary = _getBinary(metadataPath, content);
055
056        String cachePath = _getCacheDirectory(metadataPath, binary.getFilename(), content.getName(), siteName);
057        try
058        {
059            is = binary.getInputStream();
060            String md5sum = DigestUtils.md5Hex(is);
061            
062            is2 = binary.getInputStream();
063            return cache(cachePath, md5sum, is2, content.getName(), content.getId(), binary.getMimeType());
064        }
065        finally
066        {
067            IOUtils.closeQuietly(is);
068            IOUtils.closeQuietly(is2);
069        }
070    }
071    
072    private Binary _getBinary(String dataPath, Content content)
073    {
074        if (dataPath.contains("["))
075        {
076            // The path contains a repeater entry with the new syntax ("repeater[1]/myBinaryData"), the getValue method can be used
077            return content.getValue(dataPath);
078        }
079        else
080        {
081            // FILPBOOK-63: The path could contain a repeater with the old syntax ("repeater/1/myBinaryData"), look over each path segment to get the binary data
082            // TODO NEWATTRIBUTEAPI: When all generators have been migrated to the new API, this code is unnecessary
083            List<String> pathSegments = Arrays.asList(dataPath.split(ModelItem.ITEM_PATH_SEPARATOR));
084            Iterator<String> pathSegmentsIt = pathSegments.iterator();
085            
086            ModelAwareDataHolder dataHolder = content;
087            Binary binary = null;
088            while (pathSegmentsIt.hasNext())
089            {
090                String pathSegment = pathSegmentsIt.next();
091                
092                if (pathSegmentsIt.hasNext())
093                {
094                    // Not the last segment: it is a repeater or a composite
095                    if (dataHolder.getType(pathSegment).getId().equals(ModelItemTypeConstants.REPEATER_TYPE_ID))
096                    {
097                        ModelAwareRepeater repeater = dataHolder.getRepeater(pathSegment);
098                        int repeaterPosition = Integer.valueOf(pathSegmentsIt.next());
099                        dataHolder = repeater.getEntry(repeaterPosition);
100                    }
101                    else
102                    {
103                        dataHolder = dataHolder.getComposite(pathSegment);
104                    }
105                }
106                else
107                {
108                    binary = dataHolder.getValue(pathSegment);
109                }
110            }
111            
112            return binary;
113        }
114    }
115    
116    private String _getCacheDirectory(String metadataPath, String fileName, String contentName, String siteName)
117    {
118        StringBuilder buff = new StringBuilder();
119        buff.append("/");
120        buff.append(siteName);
121        buff.append("/contents/");
122        buff.append(contentName);
123        buff.append("/metadatas/");
124        buff.append(metadataPath);
125        buff.append("/");
126        buff.append(FilenameUtils.encodeName(fileName));
127        
128        return buff.toString();
129    }
130}