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, 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.widgets; 029 030import org.opencms.ade.galleries.shared.I_CmsGalleryProviderConstants; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsResource; 033import org.opencms.i18n.CmsMessages; 034import org.opencms.json.JSONException; 035import org.opencms.json.JSONObject; 036import org.opencms.main.CmsLog; 037import org.opencms.main.OpenCms; 038import org.opencms.util.CmsStringUtil; 039import org.opencms.workplace.CmsDialog; 040import org.opencms.workplace.galleries.A_CmsAjaxGallery; 041import org.opencms.xml.content.I_CmsXmlContentHandler.DisplayType; 042import org.opencms.xml.types.A_CmsXmlContentValue; 043import org.opencms.xml.types.I_CmsXmlContentValue; 044 045import java.util.HashMap; 046import java.util.List; 047import java.util.Locale; 048import java.util.Map; 049import java.util.Map.Entry; 050 051import org.apache.commons.logging.Log; 052 053/** 054 * Base class for all ADE gallery widget implementations.<p> 055 * 056 * @since 8.0.0 057 */ 058public abstract class A_CmsAdeGalleryWidget extends A_CmsWidget implements I_CmsADEWidget { 059 060 /** The gallery JSP path. */ 061 protected static final String PATH_GALLERY_JSP = "/system/workplace/commons/gallery.jsp"; 062 063 /** The static log object for this class. */ 064 private static final Log LOG = CmsLog.getLog(A_CmsAdeGalleryWidget.class); 065 066 /** The widget configuration. */ 067 private CmsGalleryWidgetConfiguration m_widgetConfiguration; 068 069 /** 070 * Constructor.<p> 071 */ 072 public A_CmsAdeGalleryWidget() { 073 074 this(""); 075 } 076 077 /** 078 * Creates a new gallery widget with the given configuration.<p> 079 * 080 * @param configuration the configuration to use 081 */ 082 protected A_CmsAdeGalleryWidget(String configuration) { 083 084 super(configuration); 085 } 086 087 /** 088 * @see org.opencms.widgets.I_CmsADEWidget#getConfiguration(org.opencms.file.CmsObject, org.opencms.xml.types.A_CmsXmlContentValue, org.opencms.i18n.CmsMessages, org.opencms.file.CmsResource, java.util.Locale) 089 */ 090 public String getConfiguration( 091 CmsObject cms, 092 A_CmsXmlContentValue schemaType, 093 CmsMessages messages, 094 CmsResource resource, 095 Locale contentLocale) { 096 097 return getJSONConfig(cms, schemaType, messages, resource, contentLocale).toString(); 098 } 099 100 /** 101 * @see org.opencms.widgets.I_CmsADEWidget#getCssResourceLinks(org.opencms.file.CmsObject) 102 */ 103 public List<String> getCssResourceLinks(CmsObject cms) { 104 105 return null; 106 } 107 108 /** 109 * @see org.opencms.widgets.I_CmsADEWidget#getDefaultDisplayType() 110 */ 111 public DisplayType getDefaultDisplayType() { 112 113 return DisplayType.wide; 114 } 115 116 /** 117 * @see org.opencms.widgets.I_CmsWidget#getDialogWidget(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog, org.opencms.widgets.I_CmsWidgetParameter) 118 */ 119 public String getDialogWidget(CmsObject cms, I_CmsWidgetDialog widgetDialog, I_CmsWidgetParameter param) { 120 121 String id = param.getId(); 122 long idHash = id.hashCode(); 123 if (idHash < 0) { 124 // negative hash codes will not work as JS variable names, so convert them 125 idHash = -idHash; 126 // add 2^32 to the value to ensure that it is unique 127 idHash += 4294967296L; 128 } 129 StringBuffer result = new StringBuffer(512); 130 result.append("<td class=\"xmlTd\">"); 131 result.append( 132 "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"maxwidth\"><tr><td class=\"xmlTd\">"); 133 result.append("<input class=\"xmlInput textInput"); 134 if (param.hasError()) { 135 result.append(" xmlInputError"); 136 } 137 result.append("\" value=\""); 138 String value = param.getStringValue(cms); 139 result.append(value); 140 result.append("\" name=\""); 141 result.append(id); 142 result.append("\" id=\""); 143 result.append(id); 144 result.append("\" onkeyup=\"checkPreview('"); 145 result.append(id); 146 result.append("');\"></td>"); 147 result.append(widgetDialog.dialogHorizontalSpacer(10)); 148 result.append( 149 "<td><table class=\"editorbuttonbackground\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>"); 150 result.append( 151 widgetDialog.button( 152 getOpenGalleryCall(cms, widgetDialog, param, idHash), 153 null, 154 getGalleryName() + "gallery", 155 Messages.getButtonName(getGalleryName()), 156 widgetDialog.getButtonStyle())); 157 // create preview button 158 String previewClass = "hide"; 159 if (CmsStringUtil.isNotEmpty(value) && value.startsWith("/")) { 160 // show button if preview is enabled 161 previewClass = "show"; 162 } 163 result.append("<td class=\""); 164 result.append(previewClass); 165 result.append("\" id=\"preview"); 166 result.append(id); 167 result.append("\">"); 168 result.append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>"); 169 result.append( 170 widgetDialog.button( 171 getOpenPreviewCall(widgetDialog, param.getId()), 172 null, 173 "preview.png", 174 Messages.GUI_BUTTON_PREVIEW_0, 175 widgetDialog.getButtonStyle())); 176 177 result.append("</tr></table>"); 178 179 result.append("</td></tr></table>"); 180 181 result.append("</td>"); 182 result.append("</tr></table>"); 183 184 result.append("</td>"); 185 186 JSONObject additional = null; 187 try { 188 additional = getAdditionalGalleryInfo( 189 cms, 190 widgetDialog instanceof CmsDialog ? ((CmsDialog)widgetDialog).getParamResource() : null, 191 widgetDialog.getMessages(), 192 param); 193 } catch (JSONException e) { 194 LOG.error("Error parsing widget configuration", e); 195 } 196 if (additional != null) { 197 result.append("\n<script>\n"); 198 result.append("var cms_additional_").append(idHash).append("="); 199 result.append(additional.toString()).append(";\n"); 200 result.append("</script>"); 201 } 202 203 return result.toString(); 204 } 205 206 /** 207 * Returns the lower case name of the gallery, for example <code>"html"</code>.<p> 208 * 209 * @return the lower case name of the gallery 210 */ 211 public abstract String getGalleryName(); 212 213 /** 214 * @see org.opencms.widgets.I_CmsADEWidget#getInitCall() 215 */ 216 public String getInitCall() { 217 218 return null; 219 } 220 221 /** 222 * @see org.opencms.widgets.I_CmsADEWidget#getJavaScriptResourceLinks(org.opencms.file.CmsObject) 223 */ 224 public List<String> getJavaScriptResourceLinks(CmsObject cms) { 225 226 return null; 227 } 228 229 /** 230 * @see org.opencms.widgets.I_CmsADEWidget#getWidgetName() 231 */ 232 public String getWidgetName() { 233 234 return A_CmsAdeGalleryWidget.class.getName(); 235 } 236 237 /** 238 * @see org.opencms.widgets.A_CmsWidget#isCompactViewEnabled() 239 */ 240 @Override 241 public boolean isCompactViewEnabled() { 242 243 return false; 244 } 245 246 /** 247 * @see org.opencms.widgets.I_CmsADEWidget#isInternal() 248 */ 249 public boolean isInternal() { 250 251 return true; 252 } 253 254 /** 255 * Returns additional widget information encapsulated in a JSON object.<p> 256 * May be <code>null</code>.<p> 257 * 258 * @param cms an initialized instance of a CmsObject 259 * @param resource the edited resource 260 * @param messages the dialog messages 261 * @param param the widget parameter to generate the widget for 262 * 263 * @return additional widget information 264 * 265 * @throws JSONException if something goes wrong generating the JSON object 266 */ 267 protected abstract JSONObject getAdditionalGalleryInfo( 268 CmsObject cms, 269 String resource, 270 CmsMessages messages, 271 I_CmsWidgetParameter param) 272 throws JSONException; 273 274 /** 275 * Returns the required gallery open parameters. 276 * 277 * @param cms an initialized instance of a CmsObject 278 * @param messages the dialog messages 279 * @param param the widget parameter to generate the widget for 280 * @param resource the resource being edited 281 * @param hashId the field id hash 282 * 283 * @return the gallery open parameters 284 */ 285 protected Map<String, String> getGalleryOpenParams( 286 CmsObject cms, 287 CmsMessages messages, 288 I_CmsWidgetParameter param, 289 String resource, 290 long hashId) { 291 292 Map<String, String> result = new HashMap<String, String>(); 293 result.put(I_CmsGalleryProviderConstants.CONFIG_GALLERY_MODE, A_CmsAjaxGallery.MODE_WIDGET); 294 result.put(I_CmsGalleryProviderConstants.CONFIG_GALLERY_STORAGE_PREFIX, getGalleryStoragePrefix()); 295 result.put(I_CmsGalleryProviderConstants.CONFIG_RESOURCE_TYPES, getGalleryTypes()); 296 if (param.getId() != null) { 297 result.put(I_CmsGalleryProviderConstants.KEY_FIELD_ID, param.getId()); 298 // use javascript to read the current field value 299 result.put( 300 I_CmsGalleryProviderConstants.CONFIG_CURRENT_ELEMENT, 301 "'+document.getElementById('" + param.getId() + "').getAttribute('value')+'"); 302 } 303 result.put(I_CmsGalleryProviderConstants.KEY_HASH_ID, "" + hashId); 304 // the edited resource 305 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(resource)) { 306 result.put(I_CmsGalleryProviderConstants.CONFIG_REFERENCE_PATH, resource); 307 } 308 // the start up gallery path 309 CmsGalleryWidgetConfiguration configuration = getWidgetConfiguration(cms, messages, param); 310 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(configuration.getStartup())) { 311 result.put(I_CmsGalleryProviderConstants.CONFIG_GALLERY_PATH, configuration.getStartup()); 312 } 313 // set gallery types if available 314 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(configuration.getGalleryTypes())) { 315 result.put(I_CmsGalleryProviderConstants.CONFIG_GALLERY_TYPES, configuration.getGalleryTypes()); 316 } 317 result.put(I_CmsGalleryProviderConstants.CONFIG_GALLERY_NAME, getGalleryName()); 318 return result; 319 } 320 321 /** 322 * Gets the prefix for the key used to store the last selected gallery.<p> 323 * 324 * @return the key prefix 325 */ 326 protected String getGalleryStoragePrefix() { 327 328 return ""; 329 } 330 331 /** 332 * Returns the resource type names available within this gallery widget.<p> 333 * 334 * @return the resource type names 335 */ 336 protected abstract String getGalleryTypes(); 337 338 /** 339 * Returns the gallery widget configuration as a JSON object.<p> 340 * 341 * @param cms the cms context 342 * @param schemaType the schema type 343 * @param messages the messages 344 * @param resource the edited resource 345 * @param contentLocale the content locale 346 * 347 * @return the gallery widget configuration 348 */ 349 protected JSONObject getJSONConfig( 350 CmsObject cms, 351 A_CmsXmlContentValue schemaType, 352 CmsMessages messages, 353 CmsResource resource, 354 Locale contentLocale) { 355 356 JSONObject result = new JSONObject(); 357 try { 358 for (Entry<String, String> paramEntry : getGalleryOpenParams( 359 cms, 360 messages, 361 schemaType, 362 cms.getSitePath(resource), 363 0).entrySet()) { 364 result.put(paramEntry.getKey(), paramEntry.getValue()); 365 } 366 JSONObject additional = getAdditionalGalleryInfo(cms, cms.getSitePath(resource), messages, null); 367 if (additional != null) { 368 result.merge(additional, true, true); 369 } 370 result.put(I_CmsGalleryProviderConstants.CONFIG_LOCALE, contentLocale.toString()); 371 result.remove(I_CmsGalleryProviderConstants.CONFIG_CURRENT_ELEMENT); 372 } catch (JSONException e) { 373 LOG.error(e.getMessage(), e); 374 } 375 return result; 376 } 377 378 /** 379 * Returns the javascript call to open the gallery widget dialog.<p> 380 * 381 * @param cms an initialized instance of a CmsObject 382 * @param widgetDialog the dialog where the widget is used on 383 * @param param the widget parameter to generate the widget for 384 * @param hashId the field id hash 385 * 386 * @return the javascript call to open the gallery widget dialog 387 */ 388 protected String getOpenGalleryCall( 389 CmsObject cms, 390 I_CmsWidgetDialog widgetDialog, 391 I_CmsWidgetParameter param, 392 long hashId) { 393 394 StringBuffer sb = new StringBuffer(128); 395 sb.append("javascript:cmsOpenDialog('"); 396 397 // the gallery title 398 sb.append(widgetDialog.getMessages().key(Messages.getButtonName(getGalleryName()))).append("', '"); 399 400 // the gallery path 401 sb.append(OpenCms.getSystemInfo().getOpenCmsContext()).append(PATH_GALLERY_JSP); 402 403 // set the content locale 404 Locale contentLocale = widgetDialog.getLocale(); 405 try { 406 I_CmsXmlContentValue value = (I_CmsXmlContentValue)param; 407 contentLocale = value.getLocale(); 408 } catch (Exception e) { 409 // may fail if widget is not opened from xml content editor, ignore 410 } 411 sb.append("?__locale=").append(contentLocale.toString()); 412 // add other open parameters 413 for (Entry<String, String> paramEntry : getGalleryOpenParams( 414 cms, 415 widgetDialog.getMessages(), 416 param, 417 widgetDialog instanceof CmsDialog ? ((CmsDialog)widgetDialog).getParamResource() : null, 418 hashId).entrySet()) { 419 sb.append("&").append(paramEntry.getKey()).append("=").append(paramEntry.getValue()); 420 } 421 sb.append("', '").append(param.getId()).append("', 488, 650); return false;"); 422 return sb.toString(); 423 } 424 425 /** 426 * Returns the javascript call to open the preview dialog.<p> 427 * 428 * @param widgetDialog the dialog where the widget is used on 429 * @param id the field id 430 * 431 * @return the javascript call to open the preview dialog 432 */ 433 protected String getOpenPreviewCall(I_CmsWidgetDialog widgetDialog, String id) { 434 435 StringBuffer sb = new StringBuffer(64); 436 sb.append("javascript:cmsOpenPreview('").append(widgetDialog.getMessages().key(Messages.GUI_BUTTON_PREVIEW_0)); 437 sb.append("', '").append(OpenCms.getSystemInfo().getOpenCmsContext()); 438 sb.append("', '").append(id); 439 sb.append("'); return false;"); 440 return sb.toString(); 441 } 442 443 /** 444 * Returns the widget configuration.<p> 445 * 446 * @param cms an initialized instance of a CmsObject 447 * @param messages the dialog where the widget is used on 448 * @param param the widget parameter to generate the widget for 449 * 450 * @return the widget configuration 451 */ 452 protected CmsGalleryWidgetConfiguration getWidgetConfiguration( 453 CmsObject cms, 454 CmsMessages messages, 455 I_CmsWidgetParameter param) { 456 457 if (m_widgetConfiguration == null) { 458 m_widgetConfiguration = new CmsGalleryWidgetConfiguration(cms, messages, param, getConfiguration()); 459 } 460 return m_widgetConfiguration; 461 } 462 463}