001/*
002 *  Copyright 2012 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.core.ui;
017
018import java.util.List;
019import java.util.Locale;
020import java.util.Map;
021import java.util.Map.Entry;
022
023import org.apache.avalon.framework.component.Component;
024import org.apache.avalon.framework.context.Context;
025import org.apache.avalon.framework.context.ContextException;
026import org.apache.avalon.framework.context.Contextualizable;
027import org.apache.avalon.framework.service.ServiceException;
028import org.apache.avalon.framework.service.ServiceManager;
029import org.apache.avalon.framework.service.Serviceable;
030import org.apache.avalon.framework.thread.ThreadSafe;
031import org.apache.cocoon.components.ContextHelper;
032import org.apache.cocoon.xml.AttributesImpl;
033import org.apache.cocoon.xml.XMLUtils;
034import org.apache.commons.lang3.StringUtils;
035import org.xml.sax.ContentHandler;
036import org.xml.sax.SAXException;
037
038import org.ametys.core.ui.ClientSideElement.Script;
039import org.ametys.core.ui.ClientSideElement.ScriptFile;
040import org.ametys.core.util.JSONUtils;
041import org.ametys.plugins.core.ui.help.HelpManager;
042import org.ametys.runtime.plugin.component.AbstractLogEnabled;
043
044/**
045 * This helper allow to sax a client side element
046 */
047public class SAXClientSideElementHelper extends AbstractLogEnabled implements Contextualizable, Component, Serviceable, ThreadSafe
048{
049    /** Avalon role */
050    public static final String ROLE = SAXClientSideElementHelper.class.getName();
051    /** The avalon context */
052    protected Context _context;
053    
054    private JSONUtils _jsonUtils;
055    private HelpManager _helpManager;
056
057    @Override
058    public void service(ServiceManager smanager) throws ServiceException
059    {
060        _jsonUtils = (JSONUtils) smanager.lookup(JSONUtils.ROLE);
061        _helpManager = (HelpManager) smanager.lookup(HelpManager.ROLE);
062    }
063    
064    @Override
065    public void contextualize(Context context) throws ContextException
066    {
067        _context = context;
068    }
069    /**
070     * SAX a client side element
071     * @param tagName the tag name to create
072     * @param element The client side element to sax. Can not be null.
073     * @param extensionPoint the extension point of the element. 
074     * @param handler The handler where to sax
075     * @param contextualParameters Contextuals parameters transmitted by the environment.
076     * @throws SAXException If an error occured
077     */
078    public void saxDefinition(String tagName, ClientSideElement element, String extensionPoint, ContentHandler handler, Map<String, Object> contextualParameters) throws SAXException
079    {
080        try
081        {
082            List<Script> scripts = element.getScripts(contextualParameters);
083            Map objectModel = ContextHelper.getObjectModel(_context);
084            
085            Locale locale = org.apache.cocoon.i18n.I18nUtils.findLocale(objectModel, "locale", null, Locale.getDefault(), true);
086            String langCode = locale.getLanguage();
087            
088            for (Script script : scripts)
089            {
090                AttributesImpl clientSideElementAttrs = new AttributesImpl();
091                String scriptId = script.getId();
092                try
093                {
094                    String help = _helpManager.getHelp(extensionPoint, scriptId, langCode);
095                    if (StringUtils.isNotBlank(help))
096                    {
097                        clientSideElementAttrs.addCDATAAttribute("help", help);
098                    }
099                }
100                catch (Exception e)
101                {
102                    getLogger().warn("Error while getting help url for extion point : '{}' for id : '{}'", extensionPoint, scriptId, e);
103                }
104                clientSideElementAttrs.addCDATAAttribute("id", scriptId);
105                clientSideElementAttrs.addCDATAAttribute("serverId", script.getServerId());
106                clientSideElementAttrs.addCDATAAttribute("plugin", element.getPluginName());
107                XMLUtils.startElement(handler, tagName, clientSideElementAttrs);
108                
109                // Initial parameters
110                Map<String, Object> parameters = script.getParameters();
111                
112                // SAX Action (classname and initial parameters)
113                AttributesImpl attrs = new AttributesImpl();
114                attrs.addCDATAAttribute("class", script.getScriptClassname());
115                XMLUtils.createElement(handler, "action", attrs, _jsonUtils.convertObjectToJson(parameters));
116                
117                // SAX Scripts
118                XMLUtils.startElement(handler, "scripts");
119                for (ScriptFile scriptFile : script.getScriptFiles())
120                {
121                    saxScriptFile(handler, scriptFile);
122                }
123                XMLUtils.endElement(handler, "scripts");
124        
125                // SAX CSS
126                XMLUtils.startElement(handler, "css");
127                for (ScriptFile scriptFile : script.getCSSFiles())
128                {
129                    saxScriptFile(handler, scriptFile);
130                }
131                XMLUtils.endElement(handler, "css");
132        
133                XMLUtils.endElement(handler, tagName);
134            }
135        }
136        catch (Exception e)
137        {
138            throw new SAXException("An error occurred while saxing '" + extensionPoint + "#" + element.getPluginName() + "/" + element.getId() + "'", e);
139        }
140    }
141    
142    private void saxScriptFile(ContentHandler handler, ScriptFile scriptFile) throws SAXException
143    {
144        AttributesImpl fileAttrs = new AttributesImpl();
145        if (!scriptFile.isLangSpecific())
146        {
147            String rtlMode = scriptFile.getRtlMode();
148            if (rtlMode != null && !"all".equals(rtlMode))
149            {
150                fileAttrs.addCDATAAttribute("rtl", rtlMode);
151            }
152            
153            XMLUtils.createElement(handler, "file", fileAttrs, scriptFile.getPath());
154        }
155        else
156        {
157            fileAttrs.addCDATAAttribute("lang", "true");
158            XMLUtils.startElement(handler, "file", fileAttrs);
159            
160            String defaultLang = scriptFile.getDefaultLang();
161            Map<String, String> langPaths = scriptFile.getLangPaths();
162            
163            for (Entry<String, String> langPath : langPaths.entrySet())
164            {
165                AttributesImpl langAttrs = new AttributesImpl();
166                
167                String codeLang = langPath.getKey();
168                langAttrs.addCDATAAttribute("code", codeLang);
169                if (codeLang.equals(defaultLang))
170                {
171                    langAttrs.addCDATAAttribute("default", "true");
172                }
173                
174                XMLUtils.createElement(handler, "lang", langAttrs, langPath.getValue());
175            }
176
177            XMLUtils.endElement(handler, "file");
178        }
179        
180    }
181}