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.gwt.client.util; 029 030import org.opencms.gwt.client.CmsCoreProvider; 031import org.opencms.gwt.client.I_CmsHasInit; 032import org.opencms.gwt.client.ui.CmsIFrame; 033import org.opencms.gwt.client.ui.contextmenu.I_CmsActionHandler; 034import org.opencms.gwt.client.ui.contextmenu.I_CmsStringSelectHandler; 035import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle; 036import org.opencms.gwt.shared.CmsGwtConstants; 037import org.opencms.util.CmsStringUtil; 038import org.opencms.util.CmsUUID; 039 040import java.util.ArrayList; 041import java.util.Collections; 042import java.util.HashMap; 043import java.util.List; 044import java.util.Map; 045import java.util.function.Consumer; 046 047import com.google.gwt.core.client.JavaScriptObject; 048import com.google.gwt.core.client.JsArrayString; 049import com.google.gwt.user.client.Command; 050import com.google.gwt.user.client.Timer; 051import com.google.gwt.user.client.Window; 052import com.google.gwt.user.client.ui.RootPanel; 053 054/** 055 * Handler for embedded VAADIN dialogs.<p> 056 */ 057public class CmsEmbeddedDialogHandler implements I_CmsHasInit { 058 059 /** The iframe element. */ 060 private CmsIFrame m_frame; 061 062 /** The context menu handler. */ 063 private I_CmsActionHandler m_handler; 064 065 /** The on close command. */ 066 private Command m_onCloseCommand; 067 068 /** The principle select handler. */ 069 private I_CmsStringSelectHandler m_stringSelectHandler; 070 071 /** 072 * Constructor.<p> 073 */ 074 public CmsEmbeddedDialogHandler() { 075 076 // nothing to do 077 } 078 079 /** 080 * Constructor.<p> 081 * 082 * @param handler the context handler 083 */ 084 public CmsEmbeddedDialogHandler(I_CmsActionHandler handler) { 085 086 this(); 087 m_handler = handler; 088 } 089 090 /** 091 * Encodes a parameter value for use in a query string. 092 * 093 * @param str the string to encode 094 * @return the encoded string 095 */ 096 public static String encodeParam(String str) { 097 098 return com.google.gwt.http.client.URL.encodeQueryString(str); 099 100 } 101 102 /** 103 * Exports native JS function cmsOpenEmbeddedDialog. 104 */ 105 public static native void exportNativeFunctions() /*-{ 106 $wnd.cmsOpenEmbeddedDialog = function(dialogId, callback, structureIds, 107 params) { 108 @org.opencms.gwt.client.util.CmsEmbeddedDialogHandler::openEmbeddedDialog(Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;Lcom/google/gwt/core/client/JsArrayString;Lcom/google/gwt/core/client/JavaScriptObject;)(dialogId, callback, structureIds, params); 109 }; 110 }-*/; 111 112 /** 113 * Called on load, exports native functions. 114 */ 115 public static void initClass() { 116 117 exportNativeFunctions(); 118 } 119 120 /** 121 * Opens the given dialog in an iframe. 122 * 123 * @param dialogId the action class 124 * @param structureIds the structure ids for the action 125 * @param finishCallback the callback to call after the dialog closes 126 */ 127 public static void openDialog(String dialogId, List<CmsUUID> structureIds, Consumer<CmsUUID> finishCallback) { 128 129 CmsEmbeddedDialogHandler handler = new CmsEmbeddedDialogHandler(new I_CmsActionHandler() { 130 131 public void leavePage(String targetUri) { 132 133 // TODO Auto-generated method stub 134 135 } 136 137 public void onSiteOrProjectChange(String sitePath, String serverLink) { 138 139 // TODO Auto-generated method stub 140 141 } 142 143 public void refreshResource(CmsUUID structureId) { 144 145 finishCallback.accept(structureId); 146 } 147 }); 148 handler.openDialog(dialogId, CmsGwtConstants.CONTEXT_TYPE_FILE_TABLE, structureIds, new HashMap<>()); 149 } 150 151 /** 152 * Opens the given dialog in an iframe. 153 * 154 * @param dialogId the action class 155 * @param structureIds the structure ids for the action 156 * @param params additional parameters to pass 157 * @param finishCallback the callback to call after the dialog closes 158 */ 159 public static void openDialog( 160 String dialogId, 161 List<CmsUUID> structureIds, 162 Map<String, String> params, 163 Consumer<CmsUUID> finishCallback) { 164 165 CmsEmbeddedDialogHandler handler = new CmsEmbeddedDialogHandler(new I_CmsActionHandler() { 166 167 public void leavePage(String targetUri) { 168 169 // TODO Auto-generated method stub 170 171 } 172 173 public void onSiteOrProjectChange(String sitePath, String serverLink) { 174 175 // TODO Auto-generated method stub 176 177 } 178 179 public void refreshResource(CmsUUID structureId) { 180 181 finishCallback.accept(structureId); 182 } 183 }); 184 handler.openDialog(dialogId, CmsGwtConstants.CONTEXT_TYPE_FILE_TABLE, structureIds, params); 185 } 186 187 /** 188 * Opens an embedded dialog. 189 * 190 * @param dialogId the dialog 191 * @param callback the onClose callback 192 * @param structureIds the structure ids 193 * @param params the parameters 194 */ 195 public static void openEmbeddedDialog( 196 String dialogId, 197 JavaScriptObject callback, 198 JsArrayString structureIds, 199 JavaScriptObject params) { 200 201 CmsEmbeddedDialogHandler handler = new CmsEmbeddedDialogHandler(); 202 if (callback != null) { 203 Command command = CmsJsUtil.convertCallbackToCommand(callback); 204 handler.setOnCloseCommand(command); 205 } 206 Map<String, String> paramsMap = new HashMap<>(); 207 if (params != null) { 208 CmsJsUtil.fillStringMapFromJsObject(params, paramsMap); 209 } 210 List<CmsUUID> uuids = new ArrayList<>(); 211 if (structureIds != null) { 212 for (int i = 0; i < structureIds.length(); i++) { 213 String uuidStr = structureIds.get(i); 214 try { 215 uuids.add(new CmsUUID(uuidStr)); 216 } catch (Exception e) { 217 CmsDebugLog.consoleLog(e.getClass() + ":" + e.getLocalizedMessage()); 218 } 219 } 220 } 221 handler.openDialog(dialogId, null, uuids, paramsMap); 222 } 223 224 /** 225 * Called on dialog close.<p> 226 * 227 * @param resources the resource ids to update as a ';' separated string.<p> 228 */ 229 public void finish(String resources) { 230 231 if (m_frame != null) { 232 m_frame.removeFromParent(); 233 m_frame = null; 234 } 235 if (m_handler != null) { 236 List<CmsUUID> resourceIds = parseResources(resources); 237 if (!resourceIds.isEmpty()) { 238 m_handler.refreshResource(resourceIds.get(0)); 239 } 240 } 241 if (m_onCloseCommand != null) { 242 m_onCloseCommand.execute(); 243 } 244 } 245 246 /** 247 * Returns if the dialog iframe is attached.<p> 248 * 249 * @return <code>true</code> if the dialog iframe is attached 250 */ 251 public boolean hasDialogFrame() { 252 253 return m_frame != null; 254 } 255 256 /** 257 * Navigates to the given URI.<p> 258 * 259 * @param targetUri the target URI 260 */ 261 public void leavePage(String targetUri) { 262 263 if (m_frame != null) { 264 m_frame.removeFromParent(); 265 m_frame = null; 266 } 267 if (m_handler != null) { 268 m_handler.leavePage(targetUri); 269 } else { 270 // the timer is a workaround for weird Safari behavior, just calling Location.assign doesn't work there 271 Timer timer = new Timer() { 272 273 @Override 274 public void run() { 275 276 Window.Location.assign(targetUri); 277 } 278 }; 279 timer.schedule(10); 280 } 281 } 282 283 /** 284 * Called when site and or project have been changed.<p> 285 * 286 * @param sitePath the site path to the resource to display 287 * @param serverLink the server link to the resource to display 288 */ 289 public void onSiteOrProjectChange(String sitePath, String serverLink) { 290 291 if (m_frame != null) { 292 m_frame.removeFromParent(); 293 m_frame = null; 294 } 295 if (m_handler != null) { 296 m_handler.onSiteOrProjectChange(sitePath, serverLink); 297 } else { 298 Window.Location.assign(serverLink); 299 } 300 } 301 302 /** 303 * Opens the dialog with the given id.<p> 304 * 305 * @param dialogId the dialog id 306 * @param contextType the context type, used to check the action visibility 307 * @param resources the resource to handle 308 */ 309 public void openDialog(String dialogId, String contextType, List<CmsUUID> resources) { 310 311 openDialog(dialogId, contextType, resources, null); 312 } 313 314 /** 315 * Opens the dialog with the given id.<p> 316 * 317 * @param dialogId the dialog id 318 * @param contextType the context type, used to check the action visibility 319 * @param resources the resource to handle 320 * @param rawParams additional set of parameters to append to the query string (will not be escaped, therefore 'raw') 321 */ 322 323 public void openDialog( 324 String dialogId, 325 String contextType, 326 List<CmsUUID> resources, 327 Map<String, String> rawParams) { 328 329 String resourceIds = ""; 330 if (resources != null) { 331 for (CmsUUID id : resources) { 332 resourceIds += id.toString() + ";"; 333 } 334 } 335 String url = CmsCoreProvider.get().getEmbeddedDialogsUrl() 336 + dialogId 337 + "?resources=" 338 + resourceIds 339 + "&contextType=" 340 + contextType; 341 342 if ((rawParams != null) && !rawParams.isEmpty()) { 343 List<String> params = new ArrayList<String>(); 344 for (Map.Entry<String, String> entry : rawParams.entrySet()) { 345 params.add(encodeParam(entry.getKey()) + "=" + encodeParam(entry.getValue())); 346 } 347 url = url + "&" + CmsStringUtil.listAsString(params, "&"); 348 } 349 m_frame = new CmsIFrame("embeddedDialogFrame", url); 350 m_frame.setStyleName(I_CmsLayoutBundle.INSTANCE.dialogCss().embeddedDialogFrame()); 351 RootPanel.get().add(m_frame); 352 initIFrame(); 353 } 354 355 /** 356 * Reloads the current page.<p> 357 */ 358 public void reload() { 359 360 if (m_handler != null) { 361 String uri = Window.Location.getHref(); 362 m_handler.leavePage(uri); 363 } else { 364 Window.Location.reload(); 365 } 366 } 367 368 /** 369 * Calls the principle select handler and closes the dialog frame.<p> 370 * 371 * @param principle the principle to select 372 */ 373 public void selectString(String principle) { 374 375 if (m_frame != null) { 376 m_frame.removeFromParent(); 377 m_frame = null; 378 } 379 if (m_stringSelectHandler != null) { 380 m_stringSelectHandler.selectString(principle); 381 } 382 if (m_onCloseCommand != null) { 383 m_onCloseCommand.execute(); 384 } 385 } 386 387 /** 388 * Sets the on close command.<p> 389 * 390 * @param onCloseCommand the on close command 391 */ 392 public void setOnCloseCommand(Command onCloseCommand) { 393 394 m_onCloseCommand = onCloseCommand; 395 } 396 397 /** 398 * Sets the principle select handler.<p> 399 * 400 * @param selectHandler the principle select handler 401 */ 402 public void setStringSelectHandler(I_CmsStringSelectHandler selectHandler) { 403 404 m_stringSelectHandler = selectHandler; 405 } 406 407 /** 408 * Parses the resources string.<p> 409 * 410 * @param resources the resources 411 * 412 * @return the list of resource ids 413 */ 414 protected List<CmsUUID> parseResources(String resources) { 415 416 if (CmsStringUtil.isEmptyOrWhitespaceOnly(resources)) { 417 return Collections.emptyList(); 418 } else { 419 List<CmsUUID> result = new ArrayList<CmsUUID>(); 420 String[] resArray = resources.trim().split(";"); 421 for (int i = 0; i < resArray.length; i++) { 422 result.add(new CmsUUID(resArray[i])); 423 } 424 return result; 425 } 426 } 427 428 /** 429 * Initializes the iFrame element.<p> 430 */ 431 private native void initIFrame()/*-{ 432 var self = this; 433 $wnd.frames.embeddedDialogFrame.connector = { 434 reload : function() { 435 [email protected]::reload()(); 436 }, 437 finish : function(resources) { 438 [email protected]::finish(Ljava/lang/String;)(resources); 439 }, 440 finishForProjectOrSiteChange : function(sitePath, serverLink) { 441 [email protected]::onSiteOrProjectChange(Ljava/lang/String;Ljava/lang/String;)(sitePath,serverLink) 442 }, 443 leavePage : function(targetUri) { 444 [email protected]::leavePage(Ljava/lang/String;)(targetUri); 445 }, 446 selectString : function(value) { 447 [email protected]::selectString(Ljava/lang/String;)(value); 448 } 449 }; 450 }-*/; 451}