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.ade.containerpage.client; 029 030import org.opencms.ade.containerpage.client.ui.CmsContainerPageContainer; 031import org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel; 032import org.opencms.ade.containerpage.client.ui.CmsOptionDialog; 033import org.opencms.ade.containerpage.client.ui.I_CmsDropContainer; 034import org.opencms.ade.containerpage.shared.CmsCntPageData; 035import org.opencms.ade.containerpage.shared.CmsDialogOptionsAndInfo; 036import org.opencms.ade.contenteditor.client.CmsContentEditor; 037import org.opencms.ade.contenteditor.client.CmsEditorContext; 038import org.opencms.ade.contenteditor.client.I_CmsEditorCloseHandler; 039import org.opencms.ade.contenteditor.shared.CmsContentDefinition; 040import org.opencms.ade.contenteditor.shared.CmsEditHandlerData; 041import org.opencms.ade.publish.shared.CmsPublishOptions; 042import org.opencms.gwt.client.CmsCoreProvider; 043import org.opencms.gwt.client.CmsEditableData; 044import org.opencms.gwt.client.I_CmsEditableData; 045import org.opencms.gwt.client.ui.contenteditor.CmsContentEditorDialog; 046import org.opencms.gwt.client.ui.contenteditor.CmsContentEditorDialog.DialogOptions; 047import org.opencms.gwt.client.ui.contenteditor.I_CmsContentEditorHandler; 048import org.opencms.gwt.client.util.CmsDebugLog; 049import org.opencms.gwt.client.util.CmsDomUtil; 050import org.opencms.gwt.client.util.I_CmsSimpleCallback; 051import org.opencms.gwt.shared.CmsGwtConstants; 052import org.opencms.util.CmsStringUtil; 053import org.opencms.util.CmsUUID; 054 055import java.util.HashMap; 056import java.util.Map; 057 058import com.google.gwt.dom.client.Element; 059import com.google.gwt.http.client.URL; 060import com.google.gwt.json.client.JSONBoolean; 061import com.google.gwt.json.client.JSONNumber; 062import com.google.gwt.json.client.JSONObject; 063import com.google.gwt.json.client.JSONString; 064import com.google.gwt.user.client.Command; 065import com.google.gwt.user.client.History; 066import com.google.gwt.user.client.Window; 067 068import jsinterop.base.Js; 069 070/** 071 * The container-page editor implementation of the XML content editor handler.<p> 072 * 073 * @since 8.0.0 074 */ 075public class CmsContentEditorHandler implements I_CmsContentEditorHandler { 076 077 /** Content editor hash key whre a return to the opened editor is not possible. */ 078 private static final String EDITOR_FOR_NO_RETURN_HASH_KEY = "cE"; 079 080 /** Content editor hash key used for history management. */ 081 private static final String EDITOR_HASH_KEY = "cE:"; 082 083 /** The container-page handler. */ 084 CmsContainerpageHandler m_handler; 085 086 /** The content element to be replaced by the edited content. */ 087 CmsContainerPageElementPanel m_replaceElement; 088 089 /** The currently edited element's id. */ 090 private String m_currentElementId; 091 092 /** The depending element's id. */ 093 private String m_dependingElementId; 094 095 /** Flag indicating the content editor is currently opened. */ 096 private boolean m_editorOpened; 097 098 /** 099 * Constructor.<p> 100 * 101 * @param handler the container-page handler 102 */ 103 public CmsContentEditorHandler(CmsContainerpageHandler handler) { 104 105 m_handler = handler; 106 } 107 108 /** 109 * Closes the content editor.<p> 110 */ 111 public void closeContentEditor() { 112 113 CmsContentEditor.getInstance().closeEditor(); 114 m_editorOpened = false; 115 } 116 117 /** 118 * @see org.opencms.gwt.client.ui.contenteditor.I_CmsContentEditorHandler#onClose(java.lang.String, org.opencms.util.CmsUUID, boolean, boolean, boolean) 119 */ 120 public void onClose( 121 String sitePath, 122 CmsUUID structureId, 123 boolean isNew, 124 boolean hasChangedSettings, 125 boolean usedPublishDialog) { 126 127 if (m_currentElementId == null) { 128 m_currentElementId = structureId.toString(); 129 } 130 Runnable checkPublishLocks = () -> { 131 if (usedPublishDialog) { 132 m_handler.m_controller.startPublishLockCheck(); 133 } 134 }; 135 136 if (m_replaceElement != null) { 137 if ((m_handler.m_controller.getData().getDetailId() != null) 138 && m_replaceElement.getId().startsWith(m_handler.m_controller.getData().getDetailId().toString())) { 139 Window.Location.assign( 140 CmsStringUtil.joinPaths( 141 CmsCoreProvider.get().getVfsPrefix(), 142 CmsContainerpageController.getCurrentUri(), 143 CmsContainerpageController.getServerId(m_currentElementId))); 144 } 145 146 m_handler.replaceElement(m_replaceElement, m_currentElementId, checkPublishLocks); 147 m_replaceElement = null; 148 if (m_dependingElementId != null) { 149 m_handler.reloadElements(new String[] {m_dependingElementId}, checkPublishLocks); 150 m_dependingElementId = null; 151 } 152 } else if (m_dependingElementId != null) { 153 m_handler.reloadElements(new String[] {m_currentElementId, m_dependingElementId}, checkPublishLocks); 154 m_dependingElementId = null; 155 } else { 156 m_handler.reloadElements(new String[] {m_currentElementId}, checkPublishLocks); 157 } 158 if (m_currentElementId != null) { 159 m_handler.addToRecent(m_currentElementId); 160 } 161 m_handler.enableToolbarButtons(); 162 m_handler.activateSelection(); 163 m_handler.m_controller.setContentEditing(false); 164 m_handler.m_controller.reInitInlineEditing(); 165 m_currentElementId = null; 166 if (hasChangedSettings) { 167 m_handler.m_controller.setPageChanged(new Runnable[] {}); 168 } 169 m_editorOpened = false; 170 } 171 172 /** 173 * Opens the XML content editor.<p> 174 * 175 * @param element the container element widget 176 * @param inline <code>true</code> to open the in-line editor for the given element if available 177 * @param wasNew <code>true</code> in case this is a newly created element not previously edited 178 */ 179 public void openDialog(final CmsContainerPageElementPanel element, final boolean inline, boolean wasNew) { 180 181 if (!inline && element.hasEditHandler()) { 182 m_handler.m_controller.getEditOptions( 183 element.getId(), 184 false, 185 new I_CmsSimpleCallback<CmsDialogOptionsAndInfo>() { 186 187 public void execute(CmsDialogOptionsAndInfo editOptions) { 188 189 final I_CmsSimpleCallback<CmsUUID> editCallBack = new I_CmsSimpleCallback<CmsUUID>() { 190 191 public void execute(CmsUUID arg) { 192 193 String contentId = element.getId(); 194 if (!element.getId().startsWith(arg.toString())) { 195 // the content structure ID has changed, the current element needs to be replaced after editing 196 m_replaceElement = element; 197 contentId = arg.toString(); 198 } 199 internalOpenDialog(element, contentId, inline, wasNew); 200 } 201 }; 202 if (editOptions == null) { 203 internalOpenDialog(element, element.getId(), inline, wasNew); 204 } else if (editOptions.getOptions().getOptions().size() == 1) { 205 m_handler.m_controller.prepareForEdit( 206 element.getId(), 207 editOptions.getOptions().getOptions().get(0).getValue(), 208 editCallBack); 209 } else { 210 CmsOptionDialog dialog = new CmsOptionDialog( 211 Messages.get().key(Messages.GUI_EDIT_HANDLER_SELECT_EDIT_OPTION_0), 212 editOptions.getOptions(), 213 editOptions.getInfo(), 214 new I_CmsSimpleCallback<String>() { 215 216 public void execute(String arg) { 217 218 m_handler.m_controller.prepareForEdit(element.getId(), arg, editCallBack); 219 } 220 }); 221 dialog.addDialogClose(new Command() { 222 223 public void execute() { 224 225 cancelEdit(); 226 } 227 }); 228 dialog.center(); 229 } 230 } 231 }); 232 } else { 233 internalOpenDialog(element, element.getId(), inline, wasNew); 234 } 235 } 236 237 /** 238 * Opens the XML content editor, checking for if an edit handler is configured first.<p> 239 * 240 * @param editableData the data of the element to edit 241 * @param isNew <code>true</code> if a new resource should be created 242 * @param dependingElementId the id of a depending element 243 * @param mode the element creation mode 244 * @param handlerDataForNew the edit handler data, if we are using an edit handler to create a new element; null otherwise 245 */ 246 public void openDialog( 247 final I_CmsEditableData editableData, 248 final boolean isNew, 249 final String dependingElementId, 250 final String mode, 251 final CmsEditHandlerData handlerDataForNew) { 252 253 if (!m_editorOpened) { 254 m_editorOpened = true; 255 m_handler.disableToolbarButtons(); 256 m_handler.deactivateCurrentButton(); 257 258 if (!isNew && (editableData.getStructureId() != null) && editableData.hasEditHandler()) { 259 final String elementId = CmsContentEditor.getClientIdForEditable(editableData); 260 m_handler.m_controller.getEditOptions( 261 elementId, 262 true, 263 new I_CmsSimpleCallback<CmsDialogOptionsAndInfo>() { 264 265 public void execute(CmsDialogOptionsAndInfo editOptions) { 266 267 final I_CmsSimpleCallback<CmsUUID> editCallBack = new I_CmsSimpleCallback<CmsUUID>() { 268 269 public void execute(CmsUUID arg) { 270 271 I_CmsEditableData data = editableData; 272 if (!data.getStructureId().equals(arg)) { 273 // the content structure ID has changed, change the editableData 274 data = new CmsEditableData(data); 275 ((CmsEditableData)data).setStructureId(arg); 276 } 277 internalOpenDialog(data, isNew, dependingElementId, mode, null); 278 } 279 }; 280 if (editOptions == null) { 281 internalOpenDialog(editableData, isNew, dependingElementId, mode, null); 282 } else if (editOptions.getOptions().getOptions().size() == 1) { 283 m_handler.m_controller.prepareForEdit( 284 elementId, 285 editOptions.getOptions().getOptions().get(0).getValue(), 286 editCallBack); 287 } else { 288 CmsOptionDialog dialog = new CmsOptionDialog( 289 Messages.get().key(Messages.GUI_EDIT_HANDLER_SELECT_EDIT_OPTION_0), 290 editOptions.getOptions(), 291 editOptions.getInfo(), 292 new I_CmsSimpleCallback<String>() { 293 294 public void execute(String arg) { 295 296 m_handler.m_controller.prepareForEdit(elementId, arg, editCallBack); 297 } 298 }); 299 dialog.addDialogClose(new Command() { 300 301 public void execute() { 302 303 cancelEdit(); 304 } 305 }); 306 dialog.center(); 307 } 308 } 309 }); 310 } else { 311 internalOpenDialog(editableData, isNew, dependingElementId, mode, handlerDataForNew); 312 } 313 314 } else { 315 CmsDebugLog.getInstance().printLine("Editor is already being opened."); 316 } 317 } 318 319 /** 320 * Opens the content editor according to the history hash.<p> 321 * 322 * @param historyHash the history hash 323 */ 324 public void openEditorForHistory(String historyHash) { 325 326 if (historyHash.startsWith(EDITOR_HASH_KEY)) { 327 if (!m_editorOpened) { 328 m_editorOpened = true; 329 CmsDebugLog.getInstance().printLine("EditorHandler - Opening editor from history"); 330 m_handler.m_controller.setContentEditing(true); 331 String id = historyHash.substring(EDITOR_HASH_KEY.length(), historyHash.indexOf(";")); 332 if (id.contains(",")) { 333 String[] ids = id.split(","); 334 m_currentElementId = URL.decodePathSegment(ids[0]); 335 m_dependingElementId = URL.decodePathSegment(ids[1]); 336 } else { 337 m_currentElementId = URL.decodePathSegment(id); 338 } 339 I_CmsEditorCloseHandler onClose = new I_CmsEditorCloseHandler() { 340 341 public void onClose(boolean hasChangedSettings, boolean usedPublishDialog) { 342 343 addClosedEditorHistoryItem(); 344 CmsContentEditorHandler.this.onClose( 345 null, 346 new CmsUUID(getCurrentElementId()), 347 false, 348 hasChangedSettings, 349 usedPublishDialog); 350 } 351 }; 352 String editorLocale = CmsCoreProvider.get().getLocale(); 353 354 CmsContentEditor.getInstance().openFormEditor( 355 getEditorContext(), 356 editorLocale, 357 m_currentElementId, 358 null, 359 null, 360 null, 361 null, 362 null, 363 m_handler.m_controller.getData().getMainLocale(), 364 null, 365 onClose); 366 } 367 } else { 368 closeContentEditor(); 369 } 370 } 371 372 /** 373 * Returns the currently edited element's id.<p> 374 * 375 * @return the currently edited element's id 376 */ 377 protected String getCurrentElementId() { 378 379 return m_currentElementId; 380 } 381 382 /** 383 * Adds a history item for the closed editor.<p> 384 */ 385 void addClosedEditorHistoryItem() { 386 387 History.newItem("", false); 388 } 389 390 /** 391 * Cancels opening the editor.<p> 392 */ 393 void cancelEdit() { 394 395 m_handler.enableToolbarButtons(); 396 m_handler.activateSelection(); 397 m_handler.m_controller.setContentEditing(false); 398 m_handler.m_controller.reInitInlineEditing(); 399 m_replaceElement = null; 400 m_dependingElementId = null; 401 m_currentElementId = null; 402 m_editorOpened = false; 403 } 404 405 /** 406 * Gets the editor context to use for the Acacia editor.<p> 407 * 408 * @return the editor context 409 */ 410 CmsEditorContext getEditorContext() { 411 412 CmsEditorContext result = new CmsEditorContext(); 413 result.getPublishParameters().put( 414 CmsPublishOptions.PARAM_CONTAINERPAGE, 415 "" + CmsCoreProvider.get().getStructureId()); 416 result.getPublishParameters().put( 417 CmsPublishOptions.PARAM_DETAIL, 418 "" + CmsContainerpageController.get().getData().getDetailId()); 419 result.getPublishParameters().put(CmsPublishOptions.PARAM_START_WITH_CURRENT_PAGE, ""); 420 elemental2.dom.HTMLMetaElement meta = Js.cast( 421 elemental2.dom.DomGlobal.document.querySelector( 422 "meta[name=" + CmsGwtConstants.META_EDITOR_STYLESHEET + "]")); 423 if (meta != null) { 424 result.setEditorStylesheet(meta.content); 425 } 426 return result; 427 } 428 429 /** 430 * Opens the edit dialog.<p> 431 * 432 * @param element the element to edit 433 * @param editContentId the edit content id 434 * @param inline <code>true</code> to edit the content inline 435 * @param wasNew <code>true</code> in case this is a newly created element not previously edited 436 */ 437 void internalOpenDialog( 438 final CmsContainerPageElementPanel element, 439 String editContentId, 440 final boolean inline, 441 boolean wasNew) { 442 443 if (!m_editorOpened) { 444 m_editorOpened = true; 445 m_handler.disableToolbarButtons(); 446 m_handler.deactivateCurrentButton(); 447 m_currentElementId = editContentId; 448 final String serverId = CmsContainerpageController.getServerId(m_currentElementId); 449 final Runnable classicEdit = new Runnable() { 450 451 public void run() { 452 453 CmsEditableData editableData = new CmsEditableData(); 454 editableData.setElementLanguage(CmsCoreProvider.get().getLocale()); 455 editableData.setStructureId(new CmsUUID(serverId)); 456 editableData.setSitePath(element.getSitePath()); 457 editableData.setMainLanguage(m_handler.m_controller.getData().getMainLocale()); 458 CmsContentEditorDialog.get().openEditDialog( 459 editableData, 460 false, 461 null, 462 new DialogOptions(), 463 CmsContentEditorHandler.this); 464 } 465 }; 466 467 if (m_handler.m_controller.getData().isUseClassicEditor() || element.isNewEditorDisabled()) { 468 classicEdit.run(); 469 } else { 470 String editorLocale = CmsCoreProvider.get().getLocale(); 471 final String mainLocale; 472 if (m_handler.m_controller.getData().getMainLocale() == null) { 473 Element htmlEl = CmsDomUtil.querySelector( 474 "[" + CmsGwtConstants.ATTR_DATA_ID + "*='" + serverId + "']", 475 element.getElement()); 476 if (htmlEl != null) { 477 String entityId = htmlEl.getAttribute(CmsGwtConstants.ATTR_DATA_ID); 478 mainLocale = CmsContentDefinition.getLocaleFromId(entityId); 479 } else { 480 mainLocale = null; 481 } 482 } else { 483 mainLocale = m_handler.m_controller.getData().getMainLocale(); 484 } 485 I_CmsEditorCloseHandler onClose = new I_CmsEditorCloseHandler() { 486 487 public void onClose(boolean hasChangedSettings, boolean usedPublishDialog) { 488 489 addClosedEditorHistoryItem(); 490 CmsContentEditorHandler.this.onClose( 491 element.getSitePath(), 492 new CmsUUID(serverId), 493 false, 494 hasChangedSettings, 495 usedPublishDialog); 496 497 } 498 }; 499 if (inline && CmsContentEditor.hasEditable(element.getElement())) { 500 addEditingHistoryItem(true); 501 CmsEditorContext context = getEditorContext(); 502 context.setHtmlContextInfo(getContextInfo(element)); 503 // remove expired style before initializing the editor 504 element.setReleasedAndNotExpired(true); 505 // in case of new elements, ignore load time 506 long loadTime = wasNew ? Long.MAX_VALUE : m_handler.m_controller.getLoadTime(); 507 CmsContentEditor.getInstance().openInlineEditor( 508 context, 509 new CmsUUID(serverId), 510 editorLocale, 511 element, 512 mainLocale, 513 loadTime, 514 onClose); 515 } else { 516 addEditingHistoryItem(false); 517 Map<String, String> settingPresets = new HashMap<String, String>(); 518 CmsEditorContext context = getEditorContext(); 519 I_CmsDropContainer dropContainer = element.getParentTarget(); 520 if (dropContainer instanceof CmsContainerPageContainer) { 521 CmsContainerPageContainer container = (CmsContainerPageContainer)dropContainer; 522 settingPresets.putAll(container.getSettingPresets()); 523 } 524 context.setSettingPresets(settingPresets); 525 526 boolean allowSettings = m_handler.m_controller.getData().allowSettingsInEditor() 527 && !m_handler.m_controller.isEditingDisabled() 528 && !serverId.equals(String.valueOf(m_handler.m_controller.getData().getDetailId())); 529 I_CmsSimpleCallback<Boolean> openEditor = new I_CmsSimpleCallback<Boolean>() { 530 531 public void execute(Boolean lockedPage) { 532 533 CmsContentEditor.getInstance().openFormEditor( 534 context, 535 editorLocale, 536 serverId, 537 lockedPage.booleanValue() ? getCurrentElementId() : null, 538 null, 539 null, 540 null, 541 null, 542 mainLocale, 543 null, 544 onClose); 545 } 546 }; 547 if (allowSettings) { 548 if (m_handler.m_controller.getData().getDetailContainerPage() != null) { 549 CmsCoreProvider.get().lock( 550 m_handler.m_controller.getData().getDetailContainerPage(), 551 m_handler.m_controller.getLoadTime(), 552 openEditor); 553 } else { 554 CmsCoreProvider.get().lock( 555 CmsCoreProvider.get().getStructureId(), 556 m_handler.m_controller.getLoadTime(), 557 openEditor); 558 } 559 } else { 560 openEditor.execute(Boolean.FALSE); 561 } 562 563 } 564 } 565 } else { 566 CmsDebugLog.getInstance().printLine("Editor is already being opened."); 567 } 568 } 569 570 /** 571 * Opens the XML content editor internally.<p> 572 * 573 * @param editableData the data of the element to edit 574 * @param isNew <code>true</code> if a new resource should be created 575 * @param dependingElementId the id of a depending element 576 * @param mode the element creation mode 577 * @param editHandlerData the edit handler data, if we are using an edit handler to create a new element; null otherwise 578 */ 579 void internalOpenDialog( 580 final I_CmsEditableData editableData, 581 final boolean isNew, 582 String dependingElementId, 583 String mode, 584 CmsEditHandlerData editHandlerData) { 585 586 if ((editableData.getStructureId() != null) && !isNew) { 587 m_currentElementId = editableData.getStructureId().toString(); 588 } else { 589 m_currentElementId = null; 590 } 591 m_dependingElementId = dependingElementId; 592 if (m_handler.m_controller.getData().isUseClassicEditor()) { 593 CmsContentEditorDialog.get().openEditDialog(editableData, isNew, mode, new DialogOptions(), this); 594 } else { 595 String newLink = null; 596 if (isNew) { 597 newLink = editableData.getNewLink(); 598 // the new link is URL encoded twice, decode it 599 newLink = URL.decodeQueryString(newLink); 600 newLink = URL.decodeQueryString(newLink); 601 } 602 addEditingHistoryItem(isNew); 603 CmsContentEditor.getInstance().openFormEditor( 604 getEditorContext(), 605 CmsCoreProvider.get().getLocale(), 606 editableData.getStructureId().toString(), 607 null, 608 newLink, 609 null, 610 editableData.getPostCreateHandler(), 611 mode, 612 m_handler.m_controller.getData().getMainLocale(), 613 editHandlerData, 614 new I_CmsEditorCloseHandler() { 615 616 public void onClose(boolean hasChangedSettings, boolean usedPublishDialog) { 617 618 addClosedEditorHistoryItem(); 619 CmsContentEditorHandler.this.onClose( 620 editableData.getSitePath(), 621 editableData.getStructureId(), 622 isNew, 623 hasChangedSettings, 624 usedPublishDialog); 625 } 626 }); 627 } 628 629 } 630 631 /** 632 * Adds a history item for the opened editor.<p> 633 * Use the prohibitReturn flag to deny a return to the opened editor through the browser history. 634 * Use this feature for inline editing or when opening the editor for new resources.<p> 635 * 636 * @param prohibitReturn if <code>true</code> returning to the opened editor through the browser history is denied 637 */ 638 private void addEditingHistoryItem(boolean prohibitReturn) { 639 640 if (prohibitReturn) { 641 History.newItem(EDITOR_FOR_NO_RETURN_HASH_KEY, false); 642 } else { 643 History.newItem( 644 EDITOR_HASH_KEY 645 + CmsContainerpageController.getServerId(getCurrentElementId()) 646 + (m_dependingElementId != null ? "," + m_dependingElementId + ";" : ";"), 647 false); 648 } 649 } 650 651 /** 652 * Returns the HTML context info for the given element.<p> 653 * 654 * @param element the edited element 655 * 656 * @return the JSON string 657 */ 658 private String getContextInfo(CmsContainerPageElementPanel element) { 659 660 CmsContainerPageContainer container; 661 if (m_handler.m_controller.isGroupcontainerEditing()) { 662 container = (CmsContainerPageContainer)((CmsContainerPageElementPanel)element.getParentTarget()).getParentTarget(); 663 } else { 664 container = (CmsContainerPageContainer)element.getParentTarget(); 665 } 666 JSONObject result = new JSONObject(); 667 putString(result, CmsCntPageData.JSONKEY_ELEMENT_ID, element.getId()); 668 CmsUUID detailId = m_handler.m_controller.getData().getDetailId(); 669 if (detailId != null) { 670 putString(result, CmsCntPageData.JSONKEY_DETAIL_ELEMENT_ID, "" + detailId); 671 } 672 putString(result, CmsCntPageData.JSONKEY_NAME, "" + container.getContainerId()); 673 putString(result, CmsCntPageData.JSONKEY_TYPE, "" + container.getContainerType()); 674 result.put(CmsCntPageData.JSONKEY_WIDTH, new JSONNumber(container.getConfiguredWidth())); 675 result.put(CmsCntPageData.JSONKEY_DETAILVIEW, JSONBoolean.getInstance(container.isDetailView())); 676 result.put( 677 CmsCntPageData.JSONKEY_ISDETAILVIEWCONTAINER, 678 JSONBoolean.getInstance(container.isDetailViewContainer())); 679 result.put(CmsCntPageData.JSONKEY_DETAILONLY, JSONBoolean.getInstance(container.isDetailOnly())); 680 result.put(CmsCntPageData.JSONKEY_MAXELEMENTS, new JSONNumber(1)); 681 JSONObject presets = new JSONObject(); 682 Map<String, String> presetsMap = container.getSettingPresets(); 683 for (Map.Entry<String, String> entry : presetsMap.entrySet()) { 684 presets.put(entry.getKey(), new JSONString(entry.getValue())); 685 } 686 result.put(CmsCntPageData.JSONKEY_PRESETS, presets); 687 return result.toString(); 688 } 689 690 /** 691 * Adds a String value to the JSON object.<p> 692 * 693 * @param obj the object to manipulate 694 * @param key the key 695 * @param val the value 696 */ 697 private void putString(JSONObject obj, String key, String val) { 698 699 obj.put(key, new JSONString(val)); 700 } 701 702}