001/*
002 *  Copyright 2021 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.core.impl.enumerator;
017
018import java.io.File;
019import java.io.IOException;
020import java.net.MalformedURLException;
021import java.util.Collection;
022import java.util.HashMap;
023import java.util.Map;
024
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.avalon.framework.service.Serviceable;
028import org.apache.commons.lang3.StringUtils;
029import org.apache.excalibur.source.SourceException;
030import org.apache.excalibur.source.SourceResolver;
031import org.apache.excalibur.source.TraversableSource;
032
033import org.ametys.runtime.i18n.I18nizableText;
034import org.ametys.runtime.model.Enumerator;
035
036/**
037 * An enumeration that list will list all the file in a source recursively.
038 * Source inside a collection will be listed as "path/to/filename"
039 */
040public abstract class AbstractTraversableSourceEnumerator implements Enumerator<String>, Serviceable
041{
042    /** The source resolver */
043    private SourceResolver _srcResolver;
044    
045    @Override
046    public void service(ServiceManager manager) throws ServiceException
047    {
048        _srcResolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
049    }
050    
051    public Map<String, I18nizableText> getTypedEntries() throws MalformedURLException, IOException
052    {
053        TraversableSource extractionDir = (TraversableSource) _srcResolver.resolveURI(getLocation());
054        
055        if (extractionDir.exists())
056        {
057            return _getCollectionFilename(extractionDir, StringUtils.EMPTY);
058        }
059        else
060        {
061            return Map.of();
062        }
063    }
064
065    /**
066     * Provide the location of the Source to extract the content from
067     * @return the location of the source
068     */
069    protected abstract String getLocation();
070
071    private Map<String, I18nizableText> _getCollectionFilename(TraversableSource source, String prefix) throws SourceException
072    {
073        Map<String, I18nizableText> filenames = new HashMap<>();
074        
075        for (TraversableSource child : (Collection<TraversableSource>) source.getChildren())
076        {
077            String childName = child.getName();
078
079            if (child.isCollection())
080            {
081                filenames.putAll(_getCollectionFilename(child, prefix + childName + File.separator));
082            }
083            else if (acceptSource(child))
084            {
085                String filePath = prefix + childName;
086                filenames.put(filePath, new I18nizableText(filePath));
087            }
088        }
089        
090        return filenames;
091    }
092
093    /**
094     * Specify if a source should be included in the result.
095     * 
096     * @param source the Source to test
097     * @return true if the source should be included, false otherwise
098     */
099    protected boolean acceptSource(TraversableSource source)
100    {
101        return true;
102    }
103
104    public I18nizableText getEntry(String value) throws Exception
105    {
106        return new I18nizableText(value);
107    }
108
109}