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.ui.components.extensions;
029
030import org.opencms.ade.galleries.shared.CmsGalleryTabConfiguration;
031import org.opencms.ade.galleries.shared.I_CmsGalleryProviderConstants;
032import org.opencms.ade.galleries.shared.I_CmsGalleryProviderConstants.GalleryMode;
033import org.opencms.ade.publish.CmsPublishService;
034import org.opencms.ade.publish.shared.CmsPublishData;
035import org.opencms.ade.publish.shared.rpc.I_CmsPublishService;
036import org.opencms.file.CmsObject;
037import org.opencms.file.CmsProject;
038import org.opencms.file.CmsResource;
039import org.opencms.gwt.CmsPrefetchSerializationPolicy;
040import org.opencms.gwt.shared.CmsHistoryVersion.OfflineOnline;
041import org.opencms.json.JSONException;
042import org.opencms.json.JSONObject;
043import org.opencms.main.CmsLog;
044import org.opencms.main.OpenCms;
045import org.opencms.ui.A_CmsUI;
046import org.opencms.ui.CmsVaadinUtils;
047import org.opencms.ui.I_CmsUpdateListener;
048import org.opencms.ui.apps.CmsAppWorkplaceUi;
049import org.opencms.ui.components.CmsErrorDialog;
050import org.opencms.ui.shared.components.I_CmsGwtDialogClientRpc;
051import org.opencms.ui.shared.components.I_CmsGwtDialogServerRpc;
052import org.opencms.util.CmsUUID;
053
054import java.util.ArrayList;
055import java.util.HashMap;
056import java.util.List;
057import java.util.Locale;
058
059import javax.servlet.http.HttpServletRequest;
060
061import org.apache.commons.logging.Log;
062
063import com.google.gwt.user.server.rpc.RPC;
064import com.vaadin.server.AbstractExtension;
065import com.vaadin.server.VaadinService;
066import com.vaadin.ui.UI;
067
068/**
069 * Extension used to open existing GWT based dialogs (from ADE, etc.) from the server side, for use in context menu actions.<p>
070 */
071public class CmsGwtDialogExtension extends AbstractExtension implements I_CmsGwtDialogServerRpc {
072
073    /** Logger instance for this class. */
074    private static final Log LOG = CmsLog.getLog(CmsGwtDialogExtension.class);
075
076    /** Serial version id. */
077    private static final long serialVersionUID = 1L;
078
079    /** The update listener. */
080    private I_CmsUpdateListener<String> m_updateListener;
081
082    /**
083     * Creates a new instance and binds it to a UI instance.<p>
084     *
085     * @param ui the UI to bind this extension to
086     * @param updateListener the update listener
087     */
088    public CmsGwtDialogExtension(UI ui, I_CmsUpdateListener<String> updateListener) {
089
090        extend(ui);
091        m_updateListener = updateListener;
092        registerRpc(this, I_CmsGwtDialogServerRpc.class);
093    }
094
095    /**
096     * Opens the dialog for editing pointer resources.<p>
097     *
098     * @param resource the pointer resource
099     */
100    public void editPointer(CmsResource resource) {
101
102        getRpcProxy(I_CmsGwtDialogClientRpc.class).editPointer("" + resource.getStructureId());
103    }
104
105    /**
106     * Open property editor for the resource with the given structure id.<p>
107     *
108     * @param structureId the structure id of a resource
109     * @param editName controls whether the file name should be editable
110     */
111    public void editProperties(CmsUUID structureId, boolean editName) {
112
113        getRpcProxy(I_CmsGwtDialogClientRpc.class).editProperties("" + structureId, editName);
114    }
115
116    /**
117     * @see org.opencms.ui.shared.components.I_CmsGwtDialogServerRpc#onClose(boolean)
118     */
119    public void onClose(boolean reinitUI) {
120
121        remove();
122        if (reinitUI) {
123            A_CmsUI.get().reload();
124        } else {
125            CmsAppWorkplaceUi.get().enableGlobalShortcuts();
126            if (m_updateListener != null) {
127                m_updateListener.onUpdate(new ArrayList<String>());
128            }
129        }
130    }
131
132    /**
133     * @see org.opencms.ui.shared.components.I_CmsGwtDialogServerRpc#onClose(java.util.List, long)
134     */
135    public void onClose(List<String> changedStructureIds, long delayMillis) {
136
137        remove();
138        if (delayMillis > 0) {
139            try {
140                Thread.sleep(delayMillis);
141            } catch (InterruptedException e) {
142                // ignore
143            }
144        }
145        A_CmsUI ui = A_CmsUI.get();
146        if (ui instanceof CmsAppWorkplaceUi) {
147            ((CmsAppWorkplaceUi)ui).enableGlobalShortcuts();
148        }
149
150        if (m_updateListener != null) {
151            m_updateListener.onUpdate(changedStructureIds);
152        }
153
154    }
155
156    /**
157     * Opens the categories dialog for the given resource.<p>
158     *
159     * @param resource the resource
160     */
161    public void openCategories(CmsResource resource) {
162
163        getRpcProxy(I_CmsGwtDialogClientRpc.class).openCategoriesDialog(
164            resource.getStructureId().toString(),
165            OpenCms.getWorkplaceManager().isDisplayCategorySelectionCollapsed());
166    }
167
168    /**
169     * Opens the content editor in a dialog for editing the provided file.
170     * @param structureId structure id of the file to edit.
171     * @param sitePath site path of the file to edit.
172     */
173    public void openContentEditor(String structureId, String sitePath) {
174
175        getRpcProxy(I_CmsGwtDialogClientRpc.class).openContentEditor(structureId, sitePath);
176    }
177
178    /**
179     * Opens the gallery dialog for the given gallery folder.<p>
180     *
181     * @param resource the gallery folder resource
182     */
183    public void openGalleryDialog(CmsResource resource) {
184
185        try {
186            CmsObject cms = A_CmsUI.getCmsObject();
187            JSONObject conf = new JSONObject();
188            conf.put(I_CmsGalleryProviderConstants.CONFIG_GALLERY_MODE, GalleryMode.view.name());
189            conf.put(I_CmsGalleryProviderConstants.CONFIG_GALLERY_PATH, cms.getSitePath(resource));
190            Locale locale = OpenCms.getLocaleManager().getDefaultLocale(cms, resource);
191            conf.put(I_CmsGalleryProviderConstants.CONFIG_LOCALE, "" + locale);
192            conf.put(I_CmsGalleryProviderConstants.CONFIG_GALLERY_STORAGE_PREFIX, "");
193            conf.put(I_CmsGalleryProviderConstants.CONFIG_TAB_CONFIG, CmsGalleryTabConfiguration.TC_SELECT_ALL);
194            getRpcProxy(I_CmsGwtDialogClientRpc.class).openGalleryDialog(conf.toString());
195        } catch (JSONException e) {
196            CmsErrorDialog.showErrorDialog(e);
197        }
198    }
199
200    /**
201     * Opens the resource info dialog.<p>
202     *
203     * @param resource the resource
204     * @param startTab the start tab id
205     */
206    public void openInfoDialog(CmsResource resource, String startTab) {
207
208        getRpcProxy(I_CmsGwtDialogClientRpc.class).openInfoDialog(resource.getStructureId().toString(), startTab);
209    }
210
211    /**
212     * Opens the lock report for the given resource.<p>
213     *
214     * @param resource the resource for which to display the lock report
215     */
216    public void openLockReport(CmsResource resource) {
217
218        String dialogTitle = CmsVaadinUtils.getMessageText(org.opencms.ui.Messages.GUI_DIALOGTITLE_LOCKREPORT_0);
219        getRpcProxy(I_CmsGwtDialogClientRpc.class).openLockReport(dialogTitle, resource.getStructureId().toString());
220    }
221
222    /**
223     * Opens the publish dialog.<p>
224     */
225    public void openPublishDialog() {
226
227        openPublishDailog(null, null);
228    }
229
230    /**
231     * Opens the publish dialog for the given project.<p>
232     *
233     * @param project the project for which to open the dialog
234     */
235    public void openPublishDialog(CmsProject project) {
236
237        openPublishDailog(project, null);
238    }
239
240    /**
241     * Tells the client to open the publish dialog for the given resources.<p>
242     *
243     * @param resources the resources for which to open the publish dialog.
244     */
245    public void openPublishDialog(List<CmsResource> resources) {
246
247        openPublishDailog(null, resources);
248    }
249
250    /**
251     * Opens the 'Replace' dialog for the resource with the given structure id.<p>
252     *
253     * @param structureId the structure id
254     */
255    public void openReplaceDialog(CmsUUID structureId) {
256
257        getRpcProxy(I_CmsGwtDialogClientRpc.class).openReplaceDialog("" + structureId);
258    }
259
260    /**
261     * Shows the OpenCms about dialog.<p>
262     */
263    public void showAbout() {
264
265        getRpcProxy(I_CmsGwtDialogClientRpc.class).showAbout();
266    }
267
268    /**
269     * Shows the prewview dialog for a given resource and version.<p>
270     *
271     * @param id the structure id of the resource
272     * @param version the version
273     * @param offlineOnline indicates whether we want the offlne or online version
274     */
275    public void showPreview(CmsUUID id, Integer version, OfflineOnline offlineOnline) {
276
277        getRpcProxy(I_CmsGwtDialogClientRpc.class).showPreview("" + id, version + ":" + offlineOnline);
278    }
279
280    /**
281     * Shows the user preferences.<p>
282     */
283    public void showUserPreferences() {
284
285        getRpcProxy(I_CmsGwtDialogClientRpc.class).showUserPreferences();
286    }
287
288    /**
289     * Gets the publish data for the given resources.<p>
290     *
291     * @param directPublishResources the resources to publish
292     * @param project the project for which to open the dialog
293     *
294     * @return the publish data for the resources
295     */
296    protected CmsPublishData getPublishData(CmsProject project, List<CmsResource> directPublishResources) {
297
298        CmsPublishService publishService = new CmsPublishService();
299        CmsObject cms = A_CmsUI.getCmsObject();
300        publishService.setCms(cms);
301        List<String> pathList = new ArrayList<String>();
302        if (directPublishResources != null) {
303            for (CmsResource resource : directPublishResources) {
304                pathList.add(cms.getSitePath(resource));
305            }
306        }
307        publishService.setRequest((HttpServletRequest)(VaadinService.getCurrentRequest()));
308        try {
309            return publishService.getPublishData(
310                cms,
311                new HashMap<String, String>()/*params*/,
312                null/*workflowId*/,
313                project != null ? project.getUuid().toString() : null /*projectParam*/,
314                pathList,
315                null/*closelink*/,
316                false/*confirmation*/);
317        } catch (Exception e) {
318            LOG.error(e.getLocalizedMessage(), e);
319            return null;
320        }
321    }
322
323    /**
324     * Serializes a CmsPublishData object into string form using the GWT serialization.<p>
325     *
326     * @param data the publish data
327     *
328     * @return the serialized publish data
329     */
330    protected String getSerializedPublishData(CmsPublishData data) {
331
332        try {
333            String prefetchedData = RPC.encodeResponseForSuccess(
334                I_CmsPublishService.class.getMethod("getInitData", java.util.HashMap.class),
335                data,
336                CmsPrefetchSerializationPolicy.instance());
337            return prefetchedData;
338        } catch (Exception e) {
339            LOG.error(e.getLocalizedMessage(), e);
340            return null;
341        }
342    }
343
344    /**
345     * Opens the publish dialog for the given project.<p>
346     *
347     * @param project the project for which to open the dialog
348     * @param directPublishResources the resources for which to open the publish dialog.
349     */
350    protected void openPublishDailog(CmsProject project, List<CmsResource> directPublishResources) {
351
352        CmsPublishData publishData = getPublishData(project, directPublishResources);
353        String data = getSerializedPublishData(publishData);
354        getRpcProxy(I_CmsGwtDialogClientRpc.class).openPublishDialog(data);
355    }
356
357}