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 * @return true if effectively saxed something, false otherwise (rights ko for example) 077 * @throws SAXException If an error occured 078 */ 079 public boolean saxDefinition(String tagName, ClientSideElement element, String extensionPoint, ContentHandler handler, Map<String, Object> contextualParameters) throws SAXException 080 { 081 try 082 { 083 List<Script> scripts = element.getScripts(contextualParameters); 084 Map objectModel = ContextHelper.getObjectModel(_context); 085 086 Locale locale = org.apache.cocoon.i18n.I18nUtils.findLocale(objectModel, "locale", null, Locale.getDefault(), true); 087 String langCode = locale.getLanguage(); 088 089 for (Script script : scripts) 090 { 091 AttributesImpl clientSideElementAttrs = new AttributesImpl(); 092 String scriptId = script.getId(); 093 try 094 { 095 String help = _helpManager.getHelp(extensionPoint, scriptId, langCode); 096 if (StringUtils.isNotBlank(help)) 097 { 098 clientSideElementAttrs.addCDATAAttribute("help", help); 099 } 100 } 101 catch (Exception e) 102 { 103 getLogger().warn("Error while getting help url for extion point : '{}' for id : '{}'", extensionPoint, scriptId, e); 104 } 105 clientSideElementAttrs.addCDATAAttribute("id", scriptId); 106 clientSideElementAttrs.addCDATAAttribute("serverId", script.getServerId()); 107 clientSideElementAttrs.addCDATAAttribute("plugin", element.getPluginName()); 108 XMLUtils.startElement(handler, tagName, clientSideElementAttrs); 109 110 // Initial parameters 111 Map<String, Object> parameters = script.getParameters(); 112 113 // SAX Action (classname and initial parameters) 114 AttributesImpl attrs = new AttributesImpl(); 115 attrs.addCDATAAttribute("class", script.getScriptClassname()); 116 XMLUtils.createElement(handler, "action", attrs, _jsonUtils.convertObjectToJson(parameters)); 117 118 // SAX Scripts 119 XMLUtils.startElement(handler, "scripts"); 120 for (ScriptFile scriptFile : script.getScriptFiles()) 121 { 122 saxScriptFile(handler, scriptFile); 123 } 124 XMLUtils.endElement(handler, "scripts"); 125 126 // SAX CSS 127 XMLUtils.startElement(handler, "css"); 128 for (ScriptFile scriptFile : script.getCSSFiles()) 129 { 130 saxScriptFile(handler, scriptFile); 131 } 132 XMLUtils.endElement(handler, "css"); 133 134 XMLUtils.endElement(handler, tagName); 135 } 136 137 return !scripts.isEmpty(); 138 } 139 catch (Exception e) 140 { 141 throw new SAXException("An error occurred while saxing '" + extensionPoint + "#" + element.getPluginName() + "/" + element.getId() + "'", e); 142 } 143 } 144 145 private void saxScriptFile(ContentHandler handler, ScriptFile scriptFile) throws SAXException 146 { 147 AttributesImpl fileAttrs = new AttributesImpl(); 148 if (!scriptFile.isLangSpecific()) 149 { 150 String rtlMode = scriptFile.getRtlMode(); 151 if (rtlMode != null && !"all".equals(rtlMode)) 152 { 153 fileAttrs.addCDATAAttribute("rtl", rtlMode); 154 } 155 156 XMLUtils.createElement(handler, "file", fileAttrs, scriptFile.getPath()); 157 } 158 else 159 { 160 fileAttrs.addCDATAAttribute("lang", "true"); 161 XMLUtils.startElement(handler, "file", fileAttrs); 162 163 String defaultLang = scriptFile.getDefaultLang(); 164 Map<String, String> langPaths = scriptFile.getLangPaths(); 165 166 for (Entry<String, String> langPath : langPaths.entrySet()) 167 { 168 AttributesImpl langAttrs = new AttributesImpl(); 169 170 String codeLang = langPath.getKey(); 171 langAttrs.addCDATAAttribute("code", codeLang); 172 if (codeLang.equals(defaultLang)) 173 { 174 langAttrs.addCDATAAttribute("default", "true"); 175 } 176 177 XMLUtils.createElement(handler, "lang", langAttrs, langPath.getValue()); 178 } 179 180 XMLUtils.endElement(handler, "file"); 181 } 182 183 } 184}