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.CmsNotification;
033import org.opencms.gwt.client.ui.CmsNotification.Type;
034import org.opencms.gwt.client.ui.contextmenu.I_CmsActionHandler;
035import org.opencms.gwt.client.ui.contextmenu.I_CmsStringSelectHandler;
036import org.opencms.gwt.shared.CmsGwtConstants;
037import org.opencms.gwt.shared.I_CmsEmbeddedDialogInfo;
038import org.opencms.util.CmsStringUtil;
039import org.opencms.util.CmsUUID;
040
041import java.util.ArrayList;
042import java.util.Collections;
043import java.util.HashMap;
044import java.util.List;
045import java.util.Map;
046import java.util.function.Consumer;
047import java.util.stream.Collectors;
048
049import com.google.gwt.core.client.JavaScriptObject;
050import com.google.gwt.core.client.JsArrayString;
051import com.google.gwt.user.client.Command;
052import com.google.gwt.user.client.Timer;
053import com.google.gwt.user.client.Window;
054import com.google.web.bindery.autobean.shared.AutoBean;
055import com.google.web.bindery.autobean.shared.AutoBeanCodex;
056
057/**
058 * Handler for embedded VAADIN dialogs.<p>
059 */
060public class CmsEmbeddedDialogHandler implements I_CmsHasInit, I_CmsEmbeddedDialogHandlerJsCallbacks {
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     * @see org.opencms.gwt.client.util.I_CmsEmbeddedDialogHandlerJsCallbacks#finish(java.lang.String)
226     */
227    @Override
228    public void finish(String resources) {
229
230        CmsEmbeddedDialogFrame.get().hide();
231        if (m_handler != null) {
232
233            List<CmsUUID> resourceIds = parseResources(resources);
234            if (!resourceIds.isEmpty()) {
235                m_handler.refreshResource(resourceIds.get(0));
236            }
237        }
238        if (m_onCloseCommand != null) {
239            m_onCloseCommand.execute();
240        }
241    }
242
243    /**
244     * Called when site and or project have been changed.<p>
245     *
246     * @param sitePath the site path to the resource to display
247     * @param serverLink the server link to the resource to display
248     */
249    @Override
250    public void finishForProjectOrSiteChange(String sitePath, String serverLink) {
251
252        CmsEmbeddedDialogFrame.get().hide();
253        if (m_handler != null) {
254            m_handler.onSiteOrProjectChange(sitePath, serverLink);
255        } else {
256            Window.Location.assign(serverLink);
257        }
258    }
259
260    /**
261     * Navigates to the given URI.<p>
262     *
263     * @param targetUri the target URI
264     */
265    @Override
266    public void leavePage(String targetUri) {
267
268        CmsEmbeddedDialogFrame.get().hide();
269        if (m_handler != null) {
270            m_handler.leavePage(targetUri);
271        } else {
272            // the timer is a workaround for weird Safari behavior, just calling Location.assign doesn't work there
273            Timer timer = new Timer() {
274
275                @Override
276                public void run() {
277
278                    Window.Location.assign(targetUri);
279                }
280            };
281            timer.schedule(10);
282        }
283    }
284
285    /**
286     * Opens the dialog with the given id.<p>
287     *
288     * @param dialogId the dialog id
289     * @param contextType the context type, used to check the action visibility
290     * @param resources the resource to handle
291     */
292    public void openDialog(String dialogId, String contextType, List<CmsUUID> resources) {
293
294        openDialog(dialogId, contextType, resources, null);
295    }
296
297    /**
298     * Opens the dialog with the given id.<p>
299     *
300     * @param dialogId the dialog id
301     * @param contextType the context type, used to check the action visibility
302     * @param resources the resource to handle
303     * @param params additional set of parameters
304     */
305
306    public void openDialog(String dialogId, String contextType, List<CmsUUID> resources, Map<String, String> params) {
307
308        AutoBean<I_CmsEmbeddedDialogInfo> info = CmsCoreProvider.AUTO_BEAN_FACTORY.createDialogInfo();
309        info.as().setDialogId(dialogId);
310        info.as().setContextType(contextType);
311        if (resources == null) {
312            resources = new ArrayList<>();
313        }
314        info.as().setStructureIds(resources.stream().map(id -> "" + id).collect(Collectors.toList()));
315        if (params == null) {
316            params = new HashMap<>();
317        }
318        info.as().setParameters(params);
319        String infoJson = AutoBeanCodex.encode(info).getPayload();
320        CmsEmbeddedDialogFrame.get().loadDialog(infoJson, this);
321    }
322
323    /**
324     * Reloads the current page.<p>
325     */
326    @Override
327    public void reload() {
328
329        if (m_handler != null) {
330            String uri = Window.Location.getHref();
331            m_handler.leavePage(uri);
332        } else {
333            Window.Location.reload();
334        }
335    }
336
337    /**
338     * Calls the principle select handler and closes the dialog frame.<p>
339     *
340     * @param principle the principle to select
341     */
342    @Override
343    public void selectString(String principle) {
344
345        CmsEmbeddedDialogFrame.get().hide();
346        if (m_stringSelectHandler != null) {
347            m_stringSelectHandler.selectString(principle);
348        }
349        if (m_onCloseCommand != null) {
350            m_onCloseCommand.execute();
351        }
352    }
353
354    /**
355     * @see org.opencms.gwt.client.util.I_CmsEmbeddedDialogHandlerJsCallbacks#sendNotification(boolean, java.lang.String)
356     */
357    @Override
358    public void sendNotification(boolean error, String notification) {
359
360        if (error) {
361            CmsNotification.get().send(Type.ERROR, notification);
362        } else {
363            CmsNotification.get().send(Type.NORMAL, notification);
364        }
365
366    }
367
368    /**
369     * Sets the on close command.<p>
370     *
371     * @param onCloseCommand the on close command
372     */
373    public void setOnCloseCommand(Command onCloseCommand) {
374
375        m_onCloseCommand = onCloseCommand;
376    }
377
378    /**
379     * Sets the principle select handler.<p>
380     *
381     * @param selectHandler the principle select handler
382     */
383    public void setStringSelectHandler(I_CmsStringSelectHandler selectHandler) {
384
385        m_stringSelectHandler = selectHandler;
386    }
387
388    /**
389     * Parses the resources string.<p>
390     *
391     * @param resources the resources
392     *
393     * @return the list of resource ids
394     */
395    protected List<CmsUUID> parseResources(String resources) {
396
397        if (CmsStringUtil.isEmptyOrWhitespaceOnly(resources)) {
398            return Collections.emptyList();
399        } else {
400            List<CmsUUID> result = new ArrayList<CmsUUID>();
401            String[] resArray = resources.trim().split(";");
402            for (int i = 0; i < resArray.length; i++) {
403                result.add(new CmsUUID(resArray[i]));
404            }
405            return result;
406        }
407    }
408
409}