001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.gwt; 029 030import org.opencms.file.CmsObject; 031import org.opencms.gwt.shared.CmsCoreData; 032import org.opencms.gwt.shared.rpc.I_CmsCoreService; 033import org.opencms.i18n.CmsEncoder; 034import org.opencms.i18n.CmsLocaleManager; 035import org.opencms.jsp.CmsJspActionElement; 036import org.opencms.main.OpenCms; 037import org.opencms.util.CmsStringUtil; 038import org.opencms.workplace.CmsWorkplace; 039 040import java.lang.reflect.Method; 041import java.util.Arrays; 042import java.util.Collection; 043import java.util.Locale; 044 045import javax.servlet.http.HttpServletRequest; 046import javax.servlet.http.HttpServletResponse; 047import javax.servlet.jsp.PageContext; 048 049import com.google.gwt.user.client.rpc.SerializationException; 050import com.google.gwt.user.server.rpc.RPC; 051 052/** 053 * Sitemap action used to generate the sitemap editor.<p> 054 * 055 * see jsp file <tt>/system/workplace/commons/sitemap.jsp</tt>.<p> 056 * 057 * @since 8.0.0 058 */ 059public class CmsGwtActionElement extends CmsJspActionElement { 060 061 /** The closing script tag. */ 062 protected static final String SCRIPT_TAG_CLOSE = "\n//-->\n</script>"; 063 064 /** The opening script tag. */ 065 protected static final String SCRIPT_TAG_OPEN = "<script>\n<!--\n"; 066 067 /** In page variable name for missing permutation message. */ 068 private static final String CMS_NO_PERMUTATION_MESSAGE = "CMS_NO_PERMUTATION_MESSAGE"; 069 070 /** The resource icon CSS URI. */ 071 private static final String ICON_CSS_URI = "/system/workplace/commons/resourceIcon.css"; 072 073 /** The current core data. */ 074 private CmsCoreData m_coreData; 075 076 /** 077 * Constructor.<p> 078 * 079 * @param context the JSP page context object 080 * @param req the JSP request 081 * @param res the JSP response 082 */ 083 public CmsGwtActionElement(PageContext context, HttpServletRequest req, HttpServletResponse res) { 084 085 super(context, req, res); 086 } 087 088 /** 089 * Returns the script tag for the "*.nocache.js".<p> 090 * 091 * @param moduleName the module name to get the script tag for 092 * @param moduleVersion the module version 093 * 094 * @return the <code>"<script>"</code> tag for the "*.nocache.js".<p> 095 */ 096 public static String createNoCacheScript(String moduleName, String moduleVersion) { 097 098 String result = "<script src=\"" 099 + CmsWorkplace.getResourceUri("ade/" + moduleName + "/" + moduleName + ".nocache.js"); 100 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(moduleVersion)) { 101 result += "?version=" + moduleVersion + "_" + OpenCms.getSystemInfo().getVersionNumber().hashCode(); 102 } 103 result += "\"></script>"; 104 return result; 105 } 106 107 /** 108 * Returns the serialized data for the core provider wrapped into a script tag.<p> 109 * 110 * @param cms the CMS context 111 * @param coreData the core data to write into the page 112 * 113 * @return the data 114 * 115 * @throws Exception if something goes wrong 116 */ 117 public static String exportCommon(CmsObject cms, CmsCoreData coreData) throws Exception { 118 119 // determine the workplace locale 120 String wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms).toString(); 121 if (CmsStringUtil.isEmptyOrWhitespaceOnly(wpLocale)) { 122 // if no locale was found, take English as locale 123 wpLocale = Locale.ENGLISH.toString(); 124 } 125 StringBuffer sb = new StringBuffer(); 126 // append meta tag to set the IE to standard document mode 127 sb.append("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n"); 128 129 sb.append( 130 "<script src=\"" 131 + OpenCms.getStaticExportManager().getVfsPrefix() 132 + "/" 133 + CmsMessagesService.class.getName() 134 + ".gwt?" 135 + CmsLocaleManager.PARAMETER_LOCALE 136 + "=" 137 + wpLocale 138 + "\"></script>\n"); 139 140 // print out the missing permutation message to be used from the nocache.js generated by custom linker 141 // see org.opencms.gwt.linker.CmsIFrameLinker 142 sb.append( 143 wrapScript( 144 "var ", 145 CMS_NO_PERMUTATION_MESSAGE, 146 "='", 147 Messages.get().getBundle(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key( 148 Messages.ERR_NO_PERMUTATION_AVAILABLE_0), 149 "';\n")); 150 151 String prefetchedData = exportDictionary( 152 CmsCoreData.DICT_NAME, 153 I_CmsCoreService.class.getMethod("prefetch"), 154 coreData); 155 sb.append(prefetchedData); 156 // sb.append(ClientMessages.get().export(wpLocale)); 157 sb.append("<style type=\"text/css\">\n @import url(\"").append(iconCssLink(cms)).append("\");\n </style>\n"); 158 159 // append additional style sheets 160 Collection<String> stylesheets = OpenCms.getWorkplaceAppManager().getAdditionalStyleSheets(); 161 for (String stylesheet : stylesheets) { 162 sb.append("<style type=\"text/css\">\n @import url(\"").append(stylesheet).append("\");\n </style>\n"); 163 } 164 // append the workplace locale information 165 sb.append("<meta name=\"gwt:property\" content=\"locale=").append(wpLocale).append("\" />\n"); 166 return sb.toString(); 167 } 168 169 /** 170 * Serializes the result of the given method for RPC-prefetching.<p> 171 * 172 * @param name the dictionary name 173 * @param method the method 174 * @param data the result to serialize 175 * 176 * @return the serialized data 177 * 178 * @throws SerializationException if something goes wrong 179 */ 180 public static String exportDictionary(String name, Method method, Object data) throws SerializationException { 181 182 return exportDictionary(name, serialize(method, data)); 183 } 184 185 /** 186 * Exports a dictionary by the given name as the content attribute of a meta tag.<p> 187 * 188 * @param name the dictionary name 189 * @param data the data 190 * 191 * @return the meta tag 192 */ 193 public static String exportDictionary(String name, String data) { 194 195 StringBuffer sb = new StringBuffer(); 196 sb.append("<meta name=\"").append(name).append("\" content=\"").append(data).append("\" />"); 197 return sb.toString(); 198 } 199 200 /** 201 * Generates the HTML for a meta tag with given name and content.<p> 202 * 203 * @param name the name of the meta tag 204 * @param data the content of the meta tag 205 * 206 * @return the HTML for the meta tag 207 */ 208 public static String exportMeta(String name, String data) { 209 210 String escName = CmsEncoder.escapeXml(name); 211 String escData = CmsEncoder.escapeXml(data); 212 return ("<meta name=\"" + escName + "\" content=\"" + escData + "\" />"); 213 } 214 215 /** 216 * Returns the OpenCms font icon CSS link.<p> 217 * 218 * @return the CSS link 219 */ 220 public static String getFontIconCssLink() { 221 222 return CmsStringUtil.joinPaths( 223 OpenCms.getSystemInfo().getContextPath(), 224 "VAADIN/themes/opencms/opencmsFonts.css"); 225 } 226 227 /** 228 * Serializes the result of the given method for RPC-prefetching.<p> 229 * 230 * @param method the method 231 * @param data the result to serialize 232 * 233 * @return the serialized data 234 * 235 * @throws SerializationException if something goes wrong 236 */ 237 public static String serialize(Method method, Object data) throws SerializationException { 238 239 String result = RPC.encodeResponseForSuccess(method, data, CmsPrefetchSerializationPolicy.instance()); 240 result = CmsEncoder.escapeXml(result, true); 241 return result; 242 } 243 244 /** 245 * Concatenates the given strings and surrounds them with script tags.<p> 246 * 247 * @param s the array of strings to concatenate and wrap 248 * 249 * @return the concatenation of the input strings, wrapped in script tags 250 */ 251 public static String wrapScript(String... s) { 252 253 return SCRIPT_TAG_OPEN + CmsStringUtil.listAsString(Arrays.asList(s), "") + SCRIPT_TAG_CLOSE; 254 } 255 256 /** 257 * Generates the link to the icon CSS JSP, and appends a "prefix" request parameter with the given value.<p> 258 * 259 * @param cms the CMS context 260 * 261 * @return the link to the icon CSS 262 */ 263 private static String iconCssLink(CmsObject cms) { 264 265 return OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, ICON_CSS_URI); 266 } 267 268 /** 269 * Returns the script tag for the "*.nocache.js".<p> 270 * 271 * @param moduleName the module name to get the script tag for 272 * 273 * @return the <code>"<script>"</code> tag for the "*.nocache.js".<p> 274 */ 275 @Deprecated 276 public String createNoCacheScript(String moduleName) { 277 278 return createNoCacheScript(moduleName, null); 279 } 280 281 /** 282 * Returns the serialized data for the core provider wrapped in a script tag.<p> 283 * 284 * @return the data 285 * 286 * @throws Exception if something goes wrong 287 */ 288 public String export() throws Exception { 289 290 return export(true); 291 } 292 293 /** 294 * Returns the serialized data for the core provider wrapped into a script tag.<p> 295 * 296 * @param includeFontCss <code>true</code> to include the OpenCms font CSS, not necessary in case VAADIN theme is loaded also 297 * 298 * @return the data 299 * 300 * @throws Exception if something goes wrong 301 */ 302 public String export(boolean includeFontCss) throws Exception { 303 304 StringBuffer buffer = new StringBuffer(exportCommon(getCmsObject(), getCoreData())); 305 if (includeFontCss || !OpenCms.getWorkplaceAppManager().getWorkplaceCssUris().isEmpty()) { 306 buffer.append("\n<style type=\"text/css\">\n"); 307 if (includeFontCss) { 308 buffer.append("@import url(\"").append(getFontIconCssLink()).append("\");\n"); 309 } 310 for (String cssURI : OpenCms.getWorkplaceAppManager().getWorkplaceCssUris()) { 311 buffer.append("@import url(\"").append(CmsWorkplace.getResourceUri(cssURI)).append("\");\n"); 312 } 313 buffer.append("</style>\n"); 314 } 315 return buffer.toString(); 316 } 317 318 /** 319 * Returns the serialized data for the core provider.<p> 320 * 321 * @return the data 322 * 323 * @throws Exception if something goes wrong 324 */ 325 public String exportAll() throws Exception { 326 327 return export(); 328 } 329 330 /** 331 * Returns the needed server data for client-side usage.<p> 332 * 333 * @return the needed server data for client-side usage 334 */ 335 public CmsCoreData getCoreData() { 336 337 if (m_coreData == null) { 338 m_coreData = CmsCoreService.prefetch(getRequest()); 339 } 340 return m_coreData; 341 } 342 343 /** 344 * Returns the workplace locale for the current user.<p> 345 * 346 * @return the workplace locale 347 */ 348 public Locale getWorkplaceLocale() { 349 350 return OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject()); 351 } 352 353 /** 354 * Exports script tag to the main OpenCms GWT no-cache js script tag.<p> 355 * 356 * @param moduleName the client module to start 357 * 358 * @return the HTML string 359 */ 360 protected String exportModuleScriptTag(String moduleName) { 361 362 String result = "<meta name=\"" 363 + CmsCoreData.META_PARAM_MODULE_KEY 364 + "\" content=\"" 365 + moduleName 366 + "\" >\n<script src=\"" 367 + CmsWorkplace.getStaticResourceUri("gwt/opencms/opencms.nocache.js"); 368 result += "\"></script>\n"; 369 return result; 370 } 371}