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 type=\"text/javascript\">\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) throws JSONException; 272 273 /** 274 * Returns the required gallery open parameters. 275 * 276 * @param cms an initialized instance of a CmsObject 277 * @param messages the dialog messages 278 * @param param the widget parameter to generate the widget for 279 * @param resource the resource being edited 280 * @param hashId the field id hash 281 * 282 * @return the gallery open parameters 283 */ 284 protected Map<String, String> getGalleryOpenParams( 285 CmsObject cms, 286 CmsMessages messages, 287 I_CmsWidgetParameter param, 288 String resource, 289 long hashId) { 290 291 Map<String, String> result = new HashMap<String, String>(); 292 result.put(I_CmsGalleryProviderConstants.CONFIG_GALLERY_MODE, A_CmsAjaxGallery.MODE_WIDGET); 293 result.put(I_CmsGalleryProviderConstants.CONFIG_GALLERY_STORAGE_PREFIX, getGalleryStoragePrefix()); 294 result.put(I_CmsGalleryProviderConstants.CONFIG_RESOURCE_TYPES, getGalleryTypes()); 295 if (param.getId() != null) { 296 result.put(I_CmsGalleryProviderConstants.KEY_FIELD_ID, param.getId()); 297 // use javascript to read the current field value 298 result.put( 299 I_CmsGalleryProviderConstants.CONFIG_CURRENT_ELEMENT, 300 "'+document.getElementById('" + param.getId() + "').getAttribute('value')+'"); 301 } 302 result.put(I_CmsGalleryProviderConstants.KEY_HASH_ID, "" + hashId); 303 // the edited resource 304 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(resource)) { 305 result.put(I_CmsGalleryProviderConstants.CONFIG_REFERENCE_PATH, resource); 306 } 307 // the start up gallery path 308 CmsGalleryWidgetConfiguration configuration = getWidgetConfiguration(cms, messages, param); 309 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(configuration.getStartup())) { 310 result.put(I_CmsGalleryProviderConstants.CONFIG_GALLERY_PATH, configuration.getStartup()); 311 } 312 // set gallery types if available 313 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(configuration.getGalleryTypes())) { 314 result.put(I_CmsGalleryProviderConstants.CONFIG_GALLERY_TYPES, configuration.getGalleryTypes()); 315 } 316 result.put(I_CmsGalleryProviderConstants.CONFIG_GALLERY_NAME, getGalleryName()); 317 return result; 318 } 319 320 /** 321 * Gets the prefix for the key used to store the last selected gallery.<p> 322 * 323 * @return the key prefix 324 */ 325 protected String getGalleryStoragePrefix() { 326 327 return ""; 328 } 329 330 /** 331 * Returns the resource type names available within this gallery widget.<p> 332 * 333 * @return the resource type names 334 */ 335 protected abstract String getGalleryTypes(); 336 337 /** 338 * Returns the gallery widget configuration as a JSON object.<p> 339 * 340 * @param cms the cms context 341 * @param schemaType the schema type 342 * @param messages the messages 343 * @param resource the edited resource 344 * @param contentLocale the content locale 345 * 346 * @return the gallery widget configuration 347 */ 348 protected JSONObject getJSONConfig( 349 CmsObject cms, 350 A_CmsXmlContentValue schemaType, 351 CmsMessages messages, 352 CmsResource resource, 353 Locale contentLocale) { 354 355 JSONObject result = new JSONObject(); 356 try { 357 for (Entry<String, String> paramEntry : getGalleryOpenParams( 358 cms, 359 messages, 360 schemaType, 361 cms.getSitePath(resource), 362 0).entrySet()) { 363 result.put(paramEntry.getKey(), paramEntry.getValue()); 364 } 365 JSONObject additional = getAdditionalGalleryInfo(cms, cms.getSitePath(resource), messages, null); 366 if (additional != null) { 367 result.merge(additional, true, true); 368 } 369 result.put(I_CmsGalleryProviderConstants.CONFIG_LOCALE, contentLocale.toString()); 370 result.remove(I_CmsGalleryProviderConstants.CONFIG_CURRENT_ELEMENT); 371 } catch (JSONException e) { 372 LOG.error(e.getMessage(), e); 373 } 374 return result; 375 } 376 377 /** 378 * Returns the javascript call to open the gallery widget dialog.<p> 379 * 380 * @param cms an initialized instance of a CmsObject 381 * @param widgetDialog the dialog where the widget is used on 382 * @param param the widget parameter to generate the widget for 383 * @param hashId the field id hash 384 * 385 * @return the javascript call to open the gallery widget dialog 386 */ 387 protected String getOpenGalleryCall( 388 CmsObject cms, 389 I_CmsWidgetDialog widgetDialog, 390 I_CmsWidgetParameter param, 391 long hashId) { 392 393 StringBuffer sb = new StringBuffer(128); 394 sb.append("javascript:cmsOpenDialog('"); 395 396 // the gallery title 397 sb.append(widgetDialog.getMessages().key(Messages.getButtonName(getGalleryName()))).append("', '"); 398 399 // the gallery path 400 sb.append(OpenCms.getSystemInfo().getOpenCmsContext()).append(PATH_GALLERY_JSP); 401 402 // set the content locale 403 Locale contentLocale = widgetDialog.getLocale(); 404 try { 405 I_CmsXmlContentValue value = (I_CmsXmlContentValue)param; 406 contentLocale = value.getLocale(); 407 } catch (Exception e) { 408 // may fail if widget is not opened from xml content editor, ignore 409 } 410 sb.append("?__locale=").append(contentLocale.toString()); 411 // add other open parameters 412 for (Entry<String, String> paramEntry : getGalleryOpenParams( 413 cms, 414 widgetDialog.getMessages(), 415 param, 416 widgetDialog instanceof CmsDialog ? ((CmsDialog)widgetDialog).getParamResource() : null, 417 hashId).entrySet()) { 418 sb.append("&").append(paramEntry.getKey()).append("=").append(paramEntry.getValue()); 419 } 420 sb.append("', '").append(param.getId()).append("', 488, 650); return false;"); 421 return sb.toString(); 422 } 423 424 /** 425 * Returns the javascript call to open the preview dialog.<p> 426 * 427 * @param widgetDialog the dialog where the widget is used on 428 * @param id the field id 429 * 430 * @return the javascript call to open the preview dialog 431 */ 432 protected String getOpenPreviewCall(I_CmsWidgetDialog widgetDialog, String id) { 433 434 StringBuffer sb = new StringBuffer(64); 435 sb.append("javascript:cmsOpenPreview('").append(widgetDialog.getMessages().key(Messages.GUI_BUTTON_PREVIEW_0)); 436 sb.append("', '").append(OpenCms.getSystemInfo().getOpenCmsContext()); 437 sb.append("', '").append(id); 438 sb.append("'); return false;"); 439 return sb.toString(); 440 } 441 442 /** 443 * Returns the widget configuration.<p> 444 * 445 * @param cms an initialized instance of a CmsObject 446 * @param messages the dialog where the widget is used on 447 * @param param the widget parameter to generate the widget for 448 * 449 * @return the widget configuration 450 */ 451 protected CmsGalleryWidgetConfiguration getWidgetConfiguration( 452 CmsObject cms, 453 CmsMessages messages, 454 I_CmsWidgetParameter param) { 455 456 if (m_widgetConfiguration == null) { 457 m_widgetConfiguration = new CmsGalleryWidgetConfiguration(cms, messages, param, getConfiguration()); 458 } 459 return m_widgetConfiguration; 460 } 461 462}