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.dublincore;
017
018import java.io.File;
019import java.io.FileFilter;
020import java.io.FileInputStream;
021import java.io.InputStream;
022import java.util.HashMap;
023import java.util.HashSet;
024import java.util.Map;
025import java.util.Set;
026
027import org.apache.avalon.framework.activity.Initializable;
028import org.apache.avalon.framework.component.Component;
029import org.apache.avalon.framework.configuration.Configuration;
030import org.apache.avalon.framework.configuration.ConfigurationException;
031import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
032import org.apache.avalon.framework.context.Context;
033import org.apache.avalon.framework.context.ContextException;
034import org.apache.avalon.framework.context.Contextualizable;
035import org.apache.avalon.framework.logger.AbstractLogEnabled;
036import org.apache.avalon.framework.thread.ThreadSafe;
037import org.apache.cocoon.Constants;
038
039import org.ametys.runtime.i18n.I18nizableText;
040
041/**
042 * This class handle the enumerated values for DublinCore metadata
043 *
044 */
045public class DublinCoreMetadataProvider extends AbstractLogEnabled implements Component, Contextualizable, ThreadSafe, Initializable
046{
047    /** Avalon Role */
048    public static final String ROLE = DublinCoreMetadataProvider.class.getName();
049    
050    private Map<String, Map<String, I18nizableText>> _entries;
051    
052    private org.apache.cocoon.environment.Context _cocoonContext;
053    
054    @Override
055    public void contextualize(Context context) throws ContextException
056    {
057        _cocoonContext = (org.apache.cocoon.environment.Context) context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
058    }
059    
060    @Override
061    public void initialize() throws Exception
062    {
063        _entries = new HashMap<>();
064    }
065    
066    /**
067     * Get the enumerated metadata names
068     * @return the enumerated metadata names
069     */
070    public Set<String> getEnumeratedMetadataNames()
071    {
072        Set<String> metadataNames = new HashSet<>();
073        
074        File dcFile = new File (_cocoonContext.getRealPath("/WEB-INF/param/dublincore"));
075        if (dcFile.exists())
076        {
077            File[] xmlFiles = dcFile.listFiles(new FileFilter()
078            {
079                @Override
080                public boolean accept(File file)
081                {
082                    return file.isFile() && file.getName().toLowerCase().endsWith(".xml");
083                }
084            });
085            
086            for (File xmlFile : xmlFiles)
087            {
088                String filename = xmlFile.getName().toLowerCase();
089                metadataNames.add(filename.substring(0, filename.lastIndexOf(".")));
090            }
091        }
092        
093        return metadataNames;
094    }
095    
096    /**
097     * Determines if the DublinCore metadata is enumerated
098     * @param metadataName the metadata name
099     * @return true if the DublinCore metadata is enumerated
100     */
101    public boolean isEnumerated (String metadataName)
102    {
103        File file = new File (_cocoonContext.getRealPath("/WEB-INF/param/dublincore/" + metadataName + ".xml"));
104        return file.exists();
105    }
106    
107    /**
108     * Provides the enumerated values
109     * @param metadataName the metadata name
110     * @return the enumerated values. Can be null.
111     */
112    public Map<String, I18nizableText> getEntries (String metadataName)
113    {
114        if (!isEnumerated(metadataName))
115        {
116            return null;
117        }
118        
119        try
120        {
121            if (!_entries.containsKey(metadataName))
122            {
123                _parseFile(metadataName);
124            }
125            
126            return _entries.get(metadataName);
127        }
128        catch (ConfigurationException e)
129        {
130            getLogger().warn("Unable to get enumerated values of DublinCore metadata '" + metadataName + "'", e);
131            return null;
132        }
133    }
134    
135    /**
136     * Retrieves a single label from a value.
137     * @param metadataName the metadata nale
138     * @param value the value.
139     * @return the label or <code>null</code> if not found.
140     */
141    public I18nizableText getEntry (String metadataName, String value)
142    {
143        if (!isEnumerated(metadataName))
144        {
145            return null;
146        }
147        
148        try
149        {
150            if (!_entries.containsKey(metadataName))
151            {
152                _parseFile(metadataName);
153            }
154            
155            return _entries.get(metadataName).get(value);
156        }
157        catch (ConfigurationException e)
158        {
159            getLogger().warn("Unable to get enumerated values of DublinCore metadata '" + metadataName + "'", e);
160            return null;
161        }
162    }
163    
164    /**
165     * Parses the enumerator.
166     * @param metadataName the metadata name
167     * @throws ConfigurationException if the configuration is not valid.
168     */
169    protected void _parseFile(String metadataName) throws ConfigurationException
170    {
171        File file = new File (_cocoonContext.getRealPath("/WEB-INF/param/dublincore/" + metadataName + ".xml"));
172        
173        if (file.exists())
174        {
175            try (InputStream is = new FileInputStream(file))
176            {
177                Configuration configuration = new DefaultConfigurationBuilder().build(is);
178                
179                Map<String, I18nizableText> entries = _parseEnumerator(configuration);
180                _entries.put(metadataName, entries);
181            }
182            catch (Exception e)
183            {
184                throw new ConfigurationException("Unable to read the configuration file " + file.getName(), e);
185            }
186        }
187    }
188    
189    /**
190     * Parses the enumerator.
191     * @param configuration the configuration to use
192     * @return the enumerator values
193     * @throws ConfigurationException if the configuration is not valid.
194     */
195    protected Map<String, I18nizableText> _parseEnumerator(Configuration configuration) throws ConfigurationException
196    {
197        Map<String, I18nizableText> entries = new HashMap<>();
198        
199        for (Configuration entryConfig : configuration.getChildren("entry"))
200        {
201            String value = entryConfig.getChild("value").getValue();
202            I18nizableText label = null;
203            
204            if (entryConfig.getChild("label", false) != null)
205            {
206                label = _parseI18nizableText(entryConfig, "label");
207            }
208            
209            entries.put(value, label);
210        }
211        
212        return entries;
213    }
214    
215    /**
216     * Parses an i18n text.
217     * @param config the configuration to use.
218     * @param name the child name.
219     * @return the i18n text.
220     * @throws ConfigurationException if the configuration is not valid.
221     */
222    protected I18nizableText _parseI18nizableText(Configuration config, String name) throws ConfigurationException
223    {
224        return I18nizableText.parseI18nizableText(config.getChild(name), "application");
225    }
226    
227    
228}