001/*
002 *  Copyright 2018 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.ui.help;
017
018import java.io.IOException;
019import java.util.ArrayList;
020import java.util.Enumeration;
021import java.util.List;
022import java.util.Locale;
023
024import org.apache.avalon.framework.component.Component;
025import org.apache.avalon.framework.context.Context;
026import org.apache.avalon.framework.context.ContextException;
027import org.apache.avalon.framework.context.Contextualizable;
028import org.apache.avalon.framework.service.ServiceException;
029import org.apache.avalon.framework.service.ServiceManager;
030import org.apache.avalon.framework.service.Serviceable;
031import org.apache.cocoon.components.ContextHelper;
032import org.apache.cocoon.environment.Request;
033import org.slf4j.Logger;
034
035import org.ametys.runtime.plugin.component.LogEnabled;
036
037import com.fasterxml.jackson.core.JsonGenerator;
038import com.fasterxml.jackson.databind.SerializerProvider;
039import com.fasterxml.jackson.databind.ser.std.StdSerializer;
040
041/**
042 * Serializer for {@link HelpLink} objects.
043 * Returns the help url for the right language, for JSON value.
044 */
045public class HelpSerializer extends StdSerializer<HelpLink> implements Component, Serviceable, LogEnabled, Contextualizable
046{
047    /** The Avalon Role */
048    public static final String ROLE = HelpSerializer.class.getName();
049    private Logger _logger;
050    private HelpManager _helpManager;
051    private Context _context;
052    
053    /**
054     * Constructor
055     */
056    public HelpSerializer()
057    {
058        super(HelpLink.class);
059    }
060
061    @Override
062    public void serialize(HelpLink value, JsonGenerator gen, SerializerProvider provider) throws IOException
063    {
064        if (value != null)
065        {
066            Request request = ContextHelper.getRequest(_context);
067            List<String> languages = _getLanguages(request);
068            try
069            {
070                String msg = _helpManager.getHelp(value.getFamily(), value.getId(), languages);
071                if (msg == null)
072                {
073                    gen.writeNull();
074                }
075                else
076                {
077                    gen.writeString(msg);
078                }
079            }
080            catch (Exception e)
081            {
082                _logger.warn("Impossible to serialize help link for point : '{}' and id : '{}'", value.getFamily(), value.getId(), e);
083            }
084        }
085    }
086
087    public void setLogger(Logger logger)
088    {
089        _logger = logger;
090    }
091
092    public void service(ServiceManager manager) throws ServiceException
093    {
094        _helpManager = (HelpManager) manager.lookup(HelpManager.ROLE);
095    }
096
097    public void contextualize(Context context) throws ContextException
098    {
099        _context = context;
100    }
101    
102    private List<String> _getLanguages(Request request)
103    {
104        List<String> languages = new ArrayList<>();
105        if (request != null)
106        {
107            Enumeration locales = request.getLocales();
108            while (locales.hasMoreElements())
109            {
110                Locale locale = (Locale) locales.nextElement();
111                String lang = locale.getLanguage();
112                if (!languages.contains(lang))
113                {
114                    languages.add(lang);
115                }
116            }
117        }
118        return languages;
119    }
120}