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;
029
030import org.opencms.ade.containerpage.CmsDetailOnlyContainerUtil;
031import org.opencms.ade.galleries.CmsPreviewService;
032import org.opencms.configuration.CmsConfigurationException;
033import org.opencms.file.CmsFile;
034import org.opencms.file.CmsObject;
035import org.opencms.file.CmsProject;
036import org.opencms.file.CmsProperty;
037import org.opencms.file.CmsPropertyDefinition;
038import org.opencms.file.CmsResource;
039import org.opencms.file.CmsResource.CmsResourceUndoMode;
040import org.opencms.file.CmsResourceFilter;
041import org.opencms.file.CmsUser;
042import org.opencms.file.CmsVfsResourceNotFoundException;
043import org.opencms.file.history.CmsHistoryProject;
044import org.opencms.file.history.I_CmsHistoryResource;
045import org.opencms.file.types.CmsResourceTypeBinary;
046import org.opencms.file.types.CmsResourceTypeFolder;
047import org.opencms.file.types.CmsResourceTypeImage;
048import org.opencms.file.types.CmsResourceTypePlain;
049import org.opencms.file.types.CmsResourceTypePointer;
050import org.opencms.file.types.CmsResourceTypeXmlContainerPage;
051import org.opencms.file.types.CmsResourceTypeXmlContent;
052import org.opencms.file.types.CmsResourceTypeXmlPage;
053import org.opencms.gwt.shared.CmsBrokenLinkBean;
054import org.opencms.gwt.shared.CmsClientDateBean;
055import org.opencms.gwt.shared.CmsDataViewConstants;
056import org.opencms.gwt.shared.CmsDeleteResourceBean;
057import org.opencms.gwt.shared.CmsExternalLinkInfoBean;
058import org.opencms.gwt.shared.CmsGwtConstants;
059import org.opencms.gwt.shared.CmsHistoryResourceBean;
060import org.opencms.gwt.shared.CmsHistoryResourceCollection;
061import org.opencms.gwt.shared.CmsHistoryVersion;
062import org.opencms.gwt.shared.CmsHistoryVersion.OfflineOnline;
063import org.opencms.gwt.shared.CmsListInfoBean;
064import org.opencms.gwt.shared.CmsListInfoBean.LockIcon;
065import org.opencms.gwt.shared.CmsLockReportInfo;
066import org.opencms.gwt.shared.CmsPrepareEditResponse;
067import org.opencms.gwt.shared.CmsPreviewInfo;
068import org.opencms.gwt.shared.CmsQuickLaunchData;
069import org.opencms.gwt.shared.CmsQuickLaunchParams;
070import org.opencms.gwt.shared.CmsRenameInfoBean;
071import org.opencms.gwt.shared.CmsReplaceInfo;
072import org.opencms.gwt.shared.CmsResourceStatusBean;
073import org.opencms.gwt.shared.CmsRestoreInfoBean;
074import org.opencms.gwt.shared.CmsVfsEntryBean;
075import org.opencms.gwt.shared.alias.CmsAliasBean;
076import org.opencms.gwt.shared.property.CmsPropertiesBean;
077import org.opencms.gwt.shared.property.CmsPropertyChangeSet;
078import org.opencms.gwt.shared.rpc.I_CmsVfsService;
079import org.opencms.i18n.CmsLocaleManager;
080import org.opencms.i18n.CmsMessageContainer;
081import org.opencms.i18n.CmsMessages;
082import org.opencms.json.JSONObject;
083import org.opencms.loader.CmsImageScaler;
084import org.opencms.loader.CmsLoaderException;
085import org.opencms.lock.CmsLock;
086import org.opencms.lock.CmsLockType;
087import org.opencms.main.CmsException;
088import org.opencms.main.CmsIllegalArgumentException;
089import org.opencms.main.CmsLog;
090import org.opencms.main.OpenCms;
091import org.opencms.relations.CmsRelation;
092import org.opencms.relations.CmsRelationFilter;
093import org.opencms.ui.components.CmsResourceIcon;
094import org.opencms.util.CmsDateUtil;
095import org.opencms.util.CmsMacroResolver;
096import org.opencms.util.CmsRequestUtil;
097import org.opencms.util.CmsStringUtil;
098import org.opencms.util.CmsUUID;
099import org.opencms.widgets.dataview.I_CmsDataView;
100import org.opencms.widgets.dataview.I_CmsDataViewItem;
101import org.opencms.workplace.comparison.CmsHistoryListUtil;
102import org.opencms.workplace.explorer.CmsExplorerTypeSettings;
103import org.opencms.workplace.explorer.CmsResourceUtil;
104import org.opencms.xml.containerpage.CmsXmlContainerPageFactory;
105import org.opencms.xml.content.CmsXmlContentFactory;
106import org.opencms.xml.content.CmsXmlContentProperty;
107import org.opencms.xml.page.CmsXmlPageFactory;
108
109import java.text.DateFormat;
110import java.util.ArrayList;
111import java.util.Collections;
112import java.util.Date;
113import java.util.HashMap;
114import java.util.HashSet;
115import java.util.LinkedHashMap;
116import java.util.List;
117import java.util.Locale;
118import java.util.Map;
119import java.util.Set;
120
121import org.apache.commons.collections.CollectionUtils;
122import org.apache.commons.logging.Log;
123
124import com.google.common.collect.HashMultimap;
125import com.google.common.collect.Lists;
126import com.google.common.collect.Multimap;
127
128/**
129 * A service class for reading the VFS tree.<p>
130 *
131 * @since 8.0.0
132 */
133public class CmsVfsService extends CmsGwtService implements I_CmsVfsService {
134
135    /** The static log object for this class. */
136    private static final Log LOG = CmsLog.getLog(CmsVfsService.class);
137
138    /** The allowed preview mime types. Checked for binary content only. */
139    private static Set<String> m_previewMimeTypes = new HashSet<String>();
140
141    /** Serialization id. */
142    private static final long serialVersionUID = -383483666952834348L;
143
144    /** Initialize the preview mime types. */
145    static {
146        CollectionUtils.addAll(
147            m_previewMimeTypes,
148            (new String[] {
149                "application/msword",
150                "application/pdf",
151                "application/excel",
152                "application/mspowerpoint",
153                "application/zip"}));
154    }
155
156    /** A helper object containing the implementations of the alias-related service methods. */
157    private CmsAliasHelper m_aliasHelper = new CmsAliasHelper();
158
159    /**
160     * Adds the lock state information to the resource info bean.<p>
161     *
162     * @param cms the CMS context
163     * @param resource the resource to get the page info for
164     * @param resourceInfo the resource info to add the lock state to
165     *
166     * @return the resource info bean
167     *
168     * @throws CmsException if something else goes wrong
169     */
170    public static CmsListInfoBean addLockInfo(CmsObject cms, CmsResource resource, CmsListInfoBean resourceInfo)
171    throws CmsException {
172
173        Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms);
174        CmsResourceUtil resourceUtil = new CmsResourceUtil(cms, resource);
175        CmsLock lock = resourceUtil.getLock();
176        LockIcon icon = LockIcon.NONE;
177        String iconTitle = null;
178        CmsLockType lockType = lock.getType();
179        if (!lock.isOwnedBy(cms.getRequestContext().getCurrentUser())) {
180            if ((lockType == CmsLockType.EXCLUSIVE)
181                || (lockType == CmsLockType.INHERITED)
182                || (lockType == CmsLockType.TEMPORARY)
183                || (lockType == CmsLockType.SHALLOW)) {
184                icon = LockIcon.CLOSED;
185            } else if ((lockType == CmsLockType.SHARED_EXCLUSIVE) || (lockType == CmsLockType.SHARED_INHERITED)) {
186                icon = LockIcon.SHARED_CLOSED;
187            }
188        } else {
189            if ((lockType == CmsLockType.EXCLUSIVE)
190                || (lockType == CmsLockType.INHERITED)
191                || (lockType == CmsLockType.TEMPORARY)
192                || (lockType == CmsLockType.SHALLOW)) {
193                icon = LockIcon.OPEN;
194            } else if ((lockType == CmsLockType.SHARED_EXCLUSIVE) || (lockType == CmsLockType.SHARED_INHERITED)) {
195                icon = LockIcon.SHARED_OPEN;
196            }
197        }
198        if ((lock.getUserId() != null) && !lock.getUserId().isNullUUID()) {
199            CmsUser lockOwner = cms.readUser(lock.getUserId());
200            iconTitle = Messages.get().getBundle(locale).key(Messages.GUI_LOCKED_BY_1, lockOwner.getFullName());
201            resourceInfo.addAdditionalInfo(
202                Messages.get().getBundle(locale).key(Messages.GUI_LOCKED_OWNER_0),
203                lockOwner.getFullName());
204        }
205        resourceInfo.setLockIcon(icon);
206        resourceInfo.setLockIconTitle(iconTitle);
207        if (icon != LockIcon.NONE) {
208            resourceInfo.setTitle(resourceInfo.getTitle() + " (" + iconTitle + ")");
209        }
210        return resourceInfo;
211    }
212
213    /**
214     * Formats a date given the current user's workplace locale.<p>
215     *
216     * @param cms the current CMS context
217     * @param date the date to format
218     *
219     * @return the formatted date
220     */
221    public static String formatDateTime(CmsObject cms, long date) {
222
223        return CmsDateUtil.getDateTime(
224            new Date(date),
225            DateFormat.MEDIUM,
226            OpenCms.getWorkplaceManager().getWorkplaceLocale(cms));
227    }
228
229    /**
230     * Returns the no preview reason if there is any.<p>
231     *
232     * @param cms the current cms context
233     * @param resource the resource to check
234     *
235     * @return the no preview reason if there is any
236     */
237    public static String getNoPreviewReason(CmsObject cms, CmsResource resource) {
238
239        Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms);
240        String noPreviewReason = null;
241        if (resource.getState().isDeleted() && !(resource instanceof I_CmsHistoryResource)) {
242            noPreviewReason = Messages.get().getBundle(locale).key(Messages.GUI_NO_PREVIEW_DELETED_0);
243        } else if (resource.isFolder()) {
244            noPreviewReason = Messages.get().getBundle(locale).key(Messages.GUI_NO_PREVIEW_FOLDER_0);
245        } else {
246            String siteRoot = OpenCms.getSiteManager().getSiteRoot(resource.getRootPath());
247            // previewing only resources that are in the same site or don't have a site root at all
248            if ((siteRoot != null) && !siteRoot.equals(cms.getRequestContext().getSiteRoot())) {
249                noPreviewReason = Messages.get().getBundle(locale).key(Messages.GUI_NO_PREVIEW_OTHER_SITE_0);
250            } else if (resource.getTypeId() == CmsResourceTypeBinary.getStaticTypeId()) {
251                String mimeType = OpenCms.getResourceManager().getMimeType(resource.getName(), null, "empty");
252                if (!m_previewMimeTypes.contains(mimeType)) {
253                    noPreviewReason = Messages.get().getBundle(locale).key(Messages.GUI_NO_PREVIEW_WRONG_MIME_TYPE_0);
254                }
255            }
256        }
257        return noPreviewReason;
258    }
259
260    /**
261     * Gets page information of a resource.<p>
262     *
263     * @param cms the CMS context
264     * @param res the resource
265     *
266     * @return gets the page information for the given resource
267     *
268     * @throws CmsException if the resource info can not be read
269     */
270    public static CmsListInfoBean getPageInfo(CmsObject cms, CmsResource res) throws CmsException {
271
272        CmsListInfoBean result = new CmsListInfoBean();
273        addPageInfo(cms, res, result);
274        return result;
275    }
276
277    /**
278     * Returns a bean to display the {@link org.opencms.gwt.client.ui.CmsListItemWidget} including the lock state.<p>
279     *
280     * @param cms the CMS context
281     * @param resource the resource to get the page info for
282     *
283     * @return a bean to display the {@link org.opencms.gwt.client.ui.CmsListItemWidget}.<p>
284     *
285     * @throws CmsLoaderException if the resource type could not be found
286     * @throws CmsException if something else goes wrong
287     */
288    public static CmsListInfoBean getPageInfoWithLock(CmsObject cms, CmsResource resource)
289    throws CmsLoaderException, CmsException {
290
291        CmsListInfoBean result = getPageInfo(cms, resource);
292        addLockInfo(cms, resource, result);
293        return result;
294    }
295
296    /**
297     * Processes a file path, which may have macros in it, so it can be opened by the XML content editor.<p>
298     *
299     * @param cms the current CMS context
300     * @param res the resource for which the context menu option has been selected
301     * @param pathWithMacros the file path which may contain macros
302     *
303     * @return the processed file path
304     */
305    public static String prepareFileNameForEditor(CmsObject cms, CmsResource res, String pathWithMacros) {
306
307        String subsite = OpenCms.getADEManager().getSubSiteRoot(cms, res.getRootPath());
308        CmsMacroResolver resolver = new CmsMacroResolver();
309        if (subsite != null) {
310            resolver.addMacro("subsite", cms.getRequestContext().removeSiteRoot(subsite));
311        }
312        resolver.addMacro("file", cms.getSitePath(res));
313        String path = resolver.resolveMacros(pathWithMacros).replaceAll("/+", "/");
314        return path;
315    }
316
317    /**
318     * Gets page information of a resource and adds it to the given list info bean.<p>
319     *
320     * @param cms the CMS context
321     * @param resource the resource
322     * @param listInfo the list info bean to add the information to
323     *
324     * @return the list info bean
325     *
326     * @throws CmsException if the resource info can not be read
327     */
328    protected static CmsListInfoBean addPageInfo(CmsObject cms, CmsResource resource, CmsListInfoBean listInfo)
329    throws CmsException {
330
331        listInfo.setResourceState(resource.getState());
332
333        String title = cms.readPropertyObject(
334            resource,
335            CmsPropertyDefinition.PROPERTY_TITLE,
336            false,
337            OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).getValue();
338        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(title)) {
339            listInfo.setTitle(title);
340        } else {
341            listInfo.setTitle(resource.getName());
342        }
343        listInfo.setSubTitle(cms.getSitePath(resource));
344        listInfo.setIsFolder(Boolean.valueOf(resource.isFolder()));
345        String resTypeName = OpenCms.getResourceManager().getResourceType(resource).getTypeName();
346        CmsExplorerTypeSettings cmsExplorerTypeSettings = OpenCms.getWorkplaceManager().getExplorerTypeSetting(
347            resTypeName);
348        if (null == cmsExplorerTypeSettings) {
349            CmsMessageContainer errMsg = Messages.get().container(
350                Messages.ERR_EXPLORER_TYPE_SETTINGS_FOR_RESOURCE_TYPE_NOT_FOUND_3,
351                resource.getRootPath(),
352                resTypeName,
353                Integer.valueOf(resource.getTypeId()));
354            throw new CmsConfigurationException(errMsg);
355        }
356        String key = cmsExplorerTypeSettings.getKey();
357        Locale currentLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms);
358        CmsMessages messages = OpenCms.getWorkplaceManager().getMessages(currentLocale);
359        String resTypeNiceName = messages.key(key);
360        listInfo.addAdditionalInfo(
361            messages.key(org.opencms.workplace.commons.Messages.GUI_LABEL_TYPE_0),
362            resTypeNiceName);
363        listInfo.setResourceType(resTypeName);
364        listInfo.setBigIconClasses(
365            CmsIconUtil.getIconClasses(CmsIconUtil.getDisplayType(cms, resource), resource.getName(), false));
366        // set the default file and detail type info
367        String detailType = CmsResourceIcon.getDefaultFileOrDetailType(cms, resource);
368        if (detailType != null) {
369            listInfo.setSmallIconClasses(CmsIconUtil.getIconClasses(detailType, null, true));
370        }
371        return listInfo;
372    }
373
374    /**
375     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#createNewExternalLink(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
376     */
377    public void createNewExternalLink(String title, String link, String resourceName, String parentFolderPath)
378    throws CmsRpcException {
379
380        CmsObject cms = getCmsObject();
381        try {
382            CmsProperty titleProp = new CmsProperty(CmsPropertyDefinition.PROPERTY_TITLE, title, null);
383            @SuppressWarnings("deprecation")
384            CmsResource resource = cms.createResource(
385                CmsStringUtil.joinPaths(parentFolderPath, resourceName),
386                CmsResourceTypePointer.getStaticTypeId(),
387                new byte[0],
388                Collections.singletonList(titleProp));
389            CmsFile file = cms.readFile(resource);
390            file.setContents(link.getBytes(CmsLocaleManager.getResourceEncoding(cms, resource)));
391            cms.writeFile(file);
392            tryUnlock(resource);
393            // update the offline search indices
394            OpenCms.getSearchManager().updateOfflineIndexes();
395        } catch (Exception e) {
396            error(e);
397        }
398    }
399
400    /**
401     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#createPropertyDefinition(java.lang.String)
402     */
403    public void createPropertyDefinition(String name) throws CmsRpcException {
404
405        CmsObject cms = getCmsObject();
406        try {
407            cms.createPropertyDefinition(name.trim());
408        } catch (Exception e) {
409            error(e);
410        }
411
412    }
413
414    /**
415     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#deleteResource(org.opencms.util.CmsUUID)
416     */
417    public void deleteResource(CmsUUID structureId) throws CmsRpcException {
418
419        try {
420            CmsObject cms = getCmsObject();
421            CmsResource res = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
422            deleteResource(res);
423        } catch (Throwable e) {
424            error(e);
425        }
426    }
427
428    /**
429     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#deleteResource(java.lang.String)
430     */
431    public void deleteResource(String sitePath) throws CmsRpcException {
432
433        try {
434            CmsResource res = getCmsObject().readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION);
435            deleteResource(res);
436        } catch (Throwable e) {
437            error(e);
438        }
439    }
440
441    /**
442     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#forceUnlock(org.opencms.util.CmsUUID)
443     */
444    public void forceUnlock(CmsUUID structureId) throws CmsRpcException {
445
446        try {
447            CmsResource resource = getCmsObject().readResource(structureId, CmsResourceFilter.ALL);
448            // get the current lock
449            CmsLock currentLock = getCmsObject().getLock(resource);
450            // check if the resource is locked at all
451            if (currentLock.getEditionLock().isUnlocked() && currentLock.getSystemLock().isUnlocked()) {
452                getCmsObject().lockResourceTemporary(resource);
453            } else {
454                getCmsObject().changeLock(resource);
455            }
456            getCmsObject().unlockResource(resource);
457        } catch (Throwable e) {
458            error(e);
459        }
460    }
461
462    /**
463     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getAliasesForPage(org.opencms.util.CmsUUID)
464     */
465    public List<CmsAliasBean> getAliasesForPage(CmsUUID uuid) throws CmsRpcException {
466
467        try {
468            return m_aliasHelper.getAliasesForPage(uuid);
469        } catch (Throwable e) {
470            error(e);
471            return null;
472        }
473    }
474
475    /**
476     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getBrokenLinks(org.opencms.util.CmsUUID)
477     */
478    public CmsDeleteResourceBean getBrokenLinks(CmsUUID structureId) throws CmsRpcException {
479
480        try {
481            CmsResource entryResource = getCmsObject().readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
482
483            return getBrokenLinks(entryResource);
484        } catch (Throwable e) {
485            error(e);
486            return null; // will never be reached
487        }
488    }
489
490    /**
491     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getBrokenLinks(java.lang.String)
492     */
493    public CmsDeleteResourceBean getBrokenLinks(String sitePath) throws CmsRpcException {
494
495        try {
496            CmsResource entryResource = getCmsObject().readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION);
497
498            return getBrokenLinks(entryResource);
499        } catch (Throwable e) {
500            error(e);
501            return null; // will never be reached
502        }
503    }
504
505    /**
506     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getChildren(java.lang.String)
507     */
508    public List<CmsVfsEntryBean> getChildren(String path) throws CmsRpcException {
509
510        try {
511            CmsObject cms = getCmsObject();
512            List<CmsResource> resources = new ArrayList<CmsResource>();
513            resources.addAll(cms.getResourcesInFolder(path, CmsResourceFilter.DEFAULT));
514            List<CmsVfsEntryBean> result = makeEntryBeans(resources, false);
515            return result;
516        } catch (Throwable e) {
517            error(e);
518        }
519        return null;
520    }
521
522    /**
523     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getDataViewThumbnail(java.lang.String, java.lang.String)
524     */
525    public String getDataViewThumbnail(String config, String id) throws CmsRpcException {
526
527        try {
528            JSONObject obj = new JSONObject(config);
529            String className = obj.optString(CmsDataViewConstants.CONFIG_VIEW_CLASS);
530            String classArg = obj.optString(CmsDataViewConstants.CONFIG_VIEW_ARG);
531            I_CmsDataView data = (I_CmsDataView)(Class.forName(className).newInstance());
532            data.initialize(getCmsObject(), classArg, OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject()));
533            I_CmsDataViewItem item = data.getItemById(id);
534            if (item == null) {
535                LOG.warn("no dataview item found for id: " + id + " (config=" + config + ")");
536                return null;
537            }
538            return item.getImage();
539        } catch (Exception e) {
540            error(e);
541            return null;
542        }
543    }
544
545    /**
546     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getDefaultProperties(java.util.List)
547     */
548    public Map<CmsUUID, Map<String, CmsXmlContentProperty>> getDefaultProperties(List<CmsUUID> structureIds)
549    throws CmsRpcException {
550
551        try {
552            CmsPropertyEditorHelper helper = new CmsPropertyEditorHelper(getCmsObject());
553            return helper.getDefaultProperties(structureIds);
554        } catch (Throwable e) {
555            error(e);
556            return null;
557        }
558    }
559
560    /**
561     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getDefinedProperties()
562     */
563    public ArrayList<String> getDefinedProperties() throws CmsRpcException {
564
565        CmsObject cms = getCmsObject();
566        try {
567            List<CmsPropertyDefinition> definitions = cms.readAllPropertyDefinitions();
568            ArrayList<String> result = new ArrayList<String>();
569            for (CmsPropertyDefinition def : definitions) {
570                result.add(def.getName());
571            }
572            return result;
573        } catch (Exception e) {
574            error(e);
575            return null;
576        }
577    }
578
579    /**
580     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getDetailName(org.opencms.util.CmsUUID, java.lang.String)
581     */
582    public String getDetailName(CmsUUID id, String localeStr) throws CmsRpcException {
583
584        CmsObject cms = getCmsObject();
585        try {
586            OpenCms.getLocaleManager();
587            Locale locale = CmsLocaleManager.getLocale(localeStr);
588            return cms.readBestUrlName(id, locale, OpenCms.getLocaleManager().getDefaultLocales());
589        } catch (Exception e) {
590            error(e);
591            return null;
592        }
593    }
594
595    /**
596     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getFileReplaceInfo(org.opencms.util.CmsUUID)
597     */
598    public CmsReplaceInfo getFileReplaceInfo(CmsUUID structureId) throws CmsRpcException {
599
600        CmsReplaceInfo result = null;
601        try {
602            CmsObject cms = getCmsObject();
603            CmsResource res = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
604            CmsListInfoBean fileInfo = getPageInfo(res);
605            boolean isLockable = cms.getLock(res).isLockableBy(cms.getRequestContext().getCurrentUser());
606            long maxFileSize = OpenCms.getWorkplaceManager().getFileBytesMaxUploadSize(cms);
607            result = new CmsReplaceInfo(fileInfo, cms.getSitePath(res), isLockable, maxFileSize);
608        } catch (Throwable e) {
609            error(e);
610        }
611        return result;
612    }
613
614    /**
615     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getHistoryPreviewInfo(org.opencms.util.CmsUUID, java.lang.String, org.opencms.gwt.shared.CmsHistoryVersion)
616     */
617    public CmsPreviewInfo getHistoryPreviewInfo(CmsUUID structureId, String locale, CmsHistoryVersion versionBean)
618    throws CmsRpcException {
619
620        try {
621            CmsObject cms = getCmsObject();
622            CmsResource previewResource = null;
623            if (versionBean.getVersionNumber() != null) {
624                previewResource = (CmsResource)(cms.readResource(
625                    structureId,
626                    versionBean.getVersionNumber().intValue()));
627            } else if (versionBean.isOffline()) {
628                previewResource = cms.readResource(structureId, CmsResourceFilter.ALL);
629            } else if (versionBean.isOnline()) {
630                CmsProject online = cms.readProject(CmsProject.ONLINE_PROJECT_ID);
631                cms = OpenCms.initCmsObject(cms);
632                cms.getRequestContext().setCurrentProject(online);
633                previewResource = cms.readResource(structureId, CmsResourceFilter.ALL);
634            }
635            CmsFile previewFile = cms.readFile(previewResource);
636            return getPreviewInfo(cms, previewFile, CmsLocaleManager.getLocale(locale));
637        } catch (Exception e) {
638            error(e);
639            return null; // return statement will never be reached
640        }
641    }
642
643    /**
644     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getLockReportInfo(org.opencms.util.CmsUUID)
645     */
646    public CmsLockReportInfo getLockReportInfo(CmsUUID structureId) throws CmsRpcException {
647
648        CmsLockReportInfo result = null;
649        CmsObject cms = getCmsObject();
650        try {
651            CmsResource resource = cms.readResource(structureId, CmsResourceFilter.ALL);
652            List<CmsListInfoBean> lockedInfos = new ArrayList<CmsListInfoBean>();
653            List<CmsResource> lockedResources = cms.getBlockingLockedResources(resource);
654            if (lockedResources != null) {
655                for (CmsResource lockedResource : lockedResources) {
656                    lockedInfos.add(getPageInfoWithLock(cms, lockedResource));
657                }
658            }
659            result = new CmsLockReportInfo(getPageInfoWithLock(cms, resource), lockedInfos);
660        } catch (Throwable e) {
661            error(e);
662        }
663        return result;
664    }
665
666    /**
667     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getPageInfo(org.opencms.util.CmsUUID)
668     */
669    public CmsListInfoBean getPageInfo(CmsUUID structureId) throws CmsRpcException {
670
671        try {
672            CmsResource res = getCmsObject().readResource(structureId, CmsResourceFilter.ALL);
673            return getPageInfo(res);
674        } catch (Throwable e) {
675            error(e);
676            return null; // will never be reached
677        }
678    }
679
680    /**
681     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getPageInfo(java.lang.String)
682     */
683    public CmsListInfoBean getPageInfo(String vfsPath) throws CmsRpcException {
684
685        try {
686            CmsResource res = getCmsObject().readResource(vfsPath, CmsResourceFilter.IGNORE_EXPIRATION);
687            return getPageInfo(res);
688        } catch (Throwable e) {
689            error(e);
690            return null; // will never be reached
691        }
692    }
693
694    /**
695     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getPreviewInfo(org.opencms.util.CmsUUID, java.lang.String)
696     */
697    public CmsPreviewInfo getPreviewInfo(CmsUUID structureId, String locale) throws CmsRpcException {
698
699        CmsPreviewInfo result = null;
700        try {
701            result = getPreviewInfo(
702                getCmsObject(),
703                getCmsObject().readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION),
704                CmsLocaleManager.getLocale(locale));
705        } catch (Exception e) {
706            error(e);
707        }
708        return result;
709
710    }
711
712    /**
713     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getPreviewInfo(java.lang.String, java.lang.String)
714     */
715    public CmsPreviewInfo getPreviewInfo(String sitePath, String locale) throws CmsRpcException {
716
717        CmsPreviewInfo result = null;
718        try {
719            result = getPreviewInfo(
720                getCmsObject(),
721                getCmsObject().readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION),
722                CmsLocaleManager.getLocale(locale));
723        } catch (Exception e) {
724            error(e);
725        }
726        return result;
727    }
728
729    /**
730     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getRenameInfo(org.opencms.util.CmsUUID)
731     */
732    public CmsRenameInfoBean getRenameInfo(CmsUUID structureId) throws CmsRpcException {
733
734        try {
735            CmsObject cms = getCmsObject();
736            CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
737            CmsListInfoBean listInfo = getPageInfo(resource);
738            String sitePath = cms.getSitePath(resource);
739            return new CmsRenameInfoBean(sitePath, structureId, listInfo);
740        } catch (Throwable e) {
741            error(e);
742            return null;
743        }
744    }
745
746    /**
747     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getResourceHistory(org.opencms.util.CmsUUID)
748     */
749    public CmsHistoryResourceCollection getResourceHistory(CmsUUID structureId) throws CmsRpcException {
750
751        try {
752            CmsHistoryResourceCollection result = getResourceHistoryInternal(structureId);
753            CmsListInfoBean info = getPageInfo(structureId);
754            result.setContentInfo(info);
755            return result;
756
757        } catch (Exception e) {
758            error(e);
759            return null; // return statement will  never be reached
760        }
761    }
762
763    /**
764     * Internal version of getResourceHistory.<p>
765     *
766     * @param structureId the structure id of the resource
767     *
768     * @return the resource history
769     *
770     * @throws CmsException if something goes wrong
771     */
772    public CmsHistoryResourceCollection getResourceHistoryInternal(CmsUUID structureId) throws CmsException {
773
774        CmsHistoryResourceCollection result = new CmsHistoryResourceCollection();
775        CmsObject cms = getCmsObject();
776        CmsResource resource = cms.readResource(structureId, CmsResourceFilter.ALL);
777        List<I_CmsHistoryResource> versions = cms.readAllAvailableVersions(resource);
778        if (!resource.getState().isUnchanged()) {
779            result.add(createHistoryResourceBean(cms, resource, true, -1));
780        }
781        int maxVersion = 0;
782
783        if (versions.isEmpty()) {
784            try {
785                CmsProject online = cms.readProject(CmsProject.ONLINE_PROJECT_ID);
786                CmsObject onlineCms = OpenCms.initCmsObject(cms);
787                onlineCms.getRequestContext().setCurrentProject(online);
788                CmsResource onlineResource = onlineCms.readResource(structureId, CmsResourceFilter.ALL);
789                CmsHistoryResourceBean onlineResBean = createHistoryResourceBean(onlineCms, onlineResource, false, 0);
790                result.add(onlineResBean);
791            } catch (CmsVfsResourceNotFoundException e) {
792                LOG.info(e.getLocalizedMessage(), e);
793            } catch (Exception e) {
794                LOG.error(e.getLocalizedMessage(), e);
795            }
796        } else {
797            for (I_CmsHistoryResource historyRes : versions) {
798                maxVersion = Math.max(maxVersion, historyRes.getVersion());
799            }
800            for (I_CmsHistoryResource historyRes : versions) {
801                CmsHistoryResourceBean historyBean = createHistoryResourceBean(
802                    cms,
803                    (CmsResource)historyRes,
804                    false,
805                    maxVersion);
806                result.add(historyBean);
807            }
808        }
809        return result;
810    }
811
812    /**
813     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getResourceStatus(org.opencms.util.CmsUUID, java.lang.String, boolean, org.opencms.util.CmsUUID, java.util.Map)
814     */
815    public CmsResourceStatusBean getResourceStatus(
816        CmsUUID structureId,
817        String contentLocale,
818        boolean includeTargets,
819        CmsUUID detailContentId,
820        Map<String, String> context)
821    throws CmsRpcException {
822
823        if (context == null) {
824            context = new HashMap<>();
825        }
826        try {
827            CmsObject cms = getCmsObject();
828            CmsDefaultResourceStatusProvider provider = new CmsDefaultResourceStatusProvider();
829            return provider.getResourceStatus(
830                getRequest(),
831                cms,
832                structureId,
833                contentLocale,
834                includeTargets,
835                detailContentId,
836                detailContentId != null ? Collections.singletonList(detailContentId) : null,
837                context);
838        } catch (Throwable e) {
839            error(e);
840            return null;
841        }
842    }
843
844    /**
845     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getRestoreInfo(org.opencms.util.CmsUUID)
846     */
847    public CmsRestoreInfoBean getRestoreInfo(CmsUUID structureId) throws CmsRpcException {
848
849        try {
850            CmsObject cms = getCmsObject();
851            CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
852            CmsListInfoBean listInfo = getPageInfo(resource);
853            CmsRestoreInfoBean result = new CmsRestoreInfoBean();
854            result.setListInfoBean(listInfo);
855
856            CmsObject onlineCms = OpenCms.initCmsObject(cms);
857            CmsProject onlineProject = cms.readProject(CmsProject.ONLINE_PROJECT_NAME);
858            onlineCms.getRequestContext().setCurrentProject(onlineProject);
859            CmsResource onlineResource = onlineCms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
860            result.setOnlinePath(onlineResource.getRootPath());
861            result.setOfflinePath(resource.getRootPath());
862
863            String offlineDate = formatDateTime(resource.getDateLastModified());
864            String onlineDate = formatDateTime(onlineResource.getDateLastModified());
865            result.setOfflineDate(offlineDate);
866            result.setOnlineDate(onlineDate);
867            result.setStructureId(structureId);
868
869            CmsObject offlineRootCms = OpenCms.initCmsObject(cms);
870            offlineRootCms.getRequestContext().setSiteRoot("");
871            CmsObject onlineRootCms = OpenCms.initCmsObject(onlineCms);
872            onlineRootCms.getRequestContext().setSiteRoot("");
873            String parent = CmsResource.getParentFolder(onlineResource.getRootPath());
874            boolean canUndoMove = offlineRootCms.existsResource(parent, CmsResourceFilter.IGNORE_EXPIRATION);
875
876            result.setCanUndoMove(canUndoMove);
877
878            return result;
879        } catch (Throwable e) {
880            error(e);
881            return null;
882        }
883    }
884
885    /**
886     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getRootEntries()
887     */
888    public List<CmsVfsEntryBean> getRootEntries() throws CmsRpcException {
889
890        try {
891            CmsObject cms = getCmsObject();
892            List<CmsResource> roots = new ArrayList<CmsResource>();
893            roots.add(cms.readResource("/", CmsResourceFilter.IGNORE_EXPIRATION));
894            return makeEntryBeans(roots, true);
895        } catch (CmsException e) {
896            error(e);
897        }
898        return null;
899    }
900
901    /**
902     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getSitePath(org.opencms.util.CmsUUID)
903     */
904    public String getSitePath(CmsUUID structureId) {
905
906        try {
907            CmsResource resource = getCmsObject().readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
908            return getCmsObject().getSitePath(resource);
909        } catch (CmsException e) {
910            if (LOG.isWarnEnabled()) {
911                LOG.warn(e.getMessageContainer(), e);
912            }
913        }
914        return null;
915    }
916
917    /**
918     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getStructureId(java.lang.String)
919     */
920    public CmsUUID getStructureId(String vfsPath) throws CmsRpcException {
921
922        try {
923            CmsResource res = getCmsObject().readResource(vfsPath, CmsResourceFilter.IGNORE_EXPIRATION);
924            return res.getStructureId();
925        } catch (Throwable e) {
926            error(e);
927            return null; // will never be reached
928        }
929    }
930
931    /**
932     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getUploadFolderInfo(java.lang.String)
933     */
934    public CmsListInfoBean getUploadFolderInfo(String path) throws CmsRpcException {
935
936        CmsObject cms = getCmsObject();
937        try {
938            CmsResource res = cms.readResource(path, CmsResourceFilter.IGNORE_EXPIRATION);
939            return getPageInfo(res);
940        } catch (CmsVfsResourceNotFoundException e) {
941            String title = CmsResource.getName(path);
942            CmsListInfoBean info = new CmsListInfoBean(title, path, new ArrayList<>());
943            info.setResourceType(CmsResourceTypeFolder.getStaticTypeName());
944            info.setBigIconClasses(CmsIconUtil.getIconClasses(CmsResourceTypeFolder.getStaticTypeName(), "", false));
945            return info;
946        } catch (Throwable e) {
947            error(e);
948            return null; // will never be reached
949        }
950    }
951
952    /**
953     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#loadLinkInfo(org.opencms.util.CmsUUID)
954     */
955    public CmsExternalLinkInfoBean loadLinkInfo(CmsUUID structureId) throws CmsRpcException {
956
957        CmsExternalLinkInfoBean info = new CmsExternalLinkInfoBean();
958        CmsObject cms = getCmsObject();
959        try {
960            CmsResource linkResource = cms.readResource(structureId, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED);
961            addPageInfo(cms, linkResource, info);
962            CmsFile linkFile = cms.readFile(linkResource);
963            OpenCms.getLocaleManager();
964            String link = new String(linkFile.getContents(), CmsLocaleManager.getResourceEncoding(cms, linkResource));
965            info.setLink(link);
966            info.setSitePath(cms.getSitePath(linkResource));
967        } catch (Exception e) {
968            error(e);
969        }
970        return info;
971    }
972
973    /**
974     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#loadPropertyData(org.opencms.util.CmsUUID)
975     */
976    public CmsPropertiesBean loadPropertyData(CmsUUID id) throws CmsRpcException {
977
978        CmsObject cms = getCmsObject();
979        try {
980            CmsPropertyEditorHelper helper = new CmsPropertyEditorHelper(cms);
981            return helper.loadPropertyData(id);
982        } catch (Throwable e) {
983            error(e);
984        }
985        return null;
986    }
987
988    /**
989     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#loadQuickLaunchItems(org.opencms.gwt.shared.CmsQuickLaunchParams)
990     */
991    public List<CmsQuickLaunchData> loadQuickLaunchItems(CmsQuickLaunchParams params) throws CmsRpcException {
992
993        try {
994            return CmsQuickLaunchProvider.getQuickLaunchData(getCmsObject(), getRequest().getSession(), params);
995        } catch (Exception e) {
996            error(e);
997            return null;
998        }
999    }
1000
1001    /**
1002     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#prepareEdit(org.opencms.util.CmsUUID, java.lang.String)
1003     */
1004    public CmsPrepareEditResponse prepareEdit(CmsUUID currentPageId, String pathWithMacros) throws CmsRpcException {
1005
1006        try {
1007            CmsObject cms = getCmsObject();
1008            CmsResource resource = null;
1009            if (cms.existsResource(pathWithMacros, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED)) {
1010                resource = cms.readResource(pathWithMacros, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED);
1011            } else {
1012                CmsResource currentPage = cms.readResource(currentPageId, CmsResourceFilter.IGNORE_EXPIRATION);
1013                String path = prepareFileNameForEditor(cms, currentPage, pathWithMacros);
1014                resource = cms.readResource(path, CmsResourceFilter.IGNORE_EXPIRATION);
1015            }
1016            ensureLock(resource);
1017            CmsPrepareEditResponse result = new CmsPrepareEditResponse();
1018            result.setRootPath(resource.getRootPath());
1019            result.setSitePath(cms.getSitePath(resource));
1020            result.setStructureId(resource.getStructureId());
1021            return result;
1022        } catch (Throwable e) {
1023            error(e);
1024        }
1025        return null;
1026    }
1027
1028    /**
1029     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#renameResource(org.opencms.util.CmsUUID, java.lang.String)
1030     */
1031    public String renameResource(CmsUUID structureId, String newName) throws CmsRpcException {
1032
1033        try {
1034            return renameResourceInternal(structureId, newName);
1035        } catch (Throwable e) {
1036            error(e);
1037            return null;
1038        }
1039    }
1040
1041    /**
1042     * Internal implementation for renaming a resource.<p>
1043     *
1044     * @param structureId the structure id of the resource to rename
1045     * @param newName the new resource name
1046     * @return either null if the rename was successful, or an error message
1047     *
1048     * @throws CmsException if something goes wrong
1049     */
1050    public String renameResourceInternal(CmsUUID structureId, String newName) throws CmsException {
1051
1052        newName = newName.trim();
1053        CmsObject rootCms = OpenCms.initCmsObject(getCmsObject());
1054        rootCms.getRequestContext().setSiteRoot("");
1055        Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(rootCms);
1056        try {
1057            CmsResource.checkResourceName(newName);
1058        } catch (CmsIllegalArgumentException e) {
1059            return e.getLocalizedMessage(locale);
1060        }
1061        CmsResource resource = rootCms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
1062        String oldPath = resource.getRootPath();
1063        String parentPath = CmsResource.getParentFolder(oldPath);
1064        String newPath = CmsStringUtil.joinPaths(parentPath, newName);
1065        try {
1066            ensureLock(resource);
1067            rootCms.moveResource(oldPath, newPath);
1068            resource = rootCms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
1069        } catch (CmsException e) {
1070            return e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(rootCms));
1071        }
1072        tryUnlock(resource);
1073        return null;
1074    }
1075
1076    /**
1077     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#restoreResource(org.opencms.util.CmsUUID, int)
1078     */
1079    public void restoreResource(CmsUUID structureId, int version) throws CmsRpcException {
1080
1081        CmsObject cms = getCmsObject();
1082        try {
1083            ensureLock(structureId);
1084            cms.restoreResourceVersion(structureId, version);
1085            try {
1086                CmsResource res = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
1087                cms.unlockResource(res);
1088            } catch (Exception e) {
1089                LOG.error(e.getLocalizedMessage(), e);
1090            }
1091
1092        } catch (Exception e) {
1093            error(e);
1094            return; // return stmt  will never be reached
1095        }
1096
1097    }
1098
1099    /**
1100     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#saveAliases(org.opencms.util.CmsUUID, java.util.List)
1101     */
1102    public void saveAliases(CmsUUID structureId, List<CmsAliasBean> aliasBeans) throws CmsRpcException {
1103
1104        try {
1105            m_aliasHelper.saveAliases(structureId, aliasBeans);
1106        } catch (Throwable e) {
1107            error(e);
1108        }
1109    }
1110
1111    /**
1112     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#saveExternalLink(org.opencms.util.CmsUUID, java.lang.String, java.lang.String, java.lang.String)
1113     */
1114    public void saveExternalLink(CmsUUID structureId, String title, String link, String fileName)
1115    throws CmsRpcException {
1116
1117        try {
1118            CmsObject cms = getCmsObject();
1119            CmsResource res = cms.readResource(structureId);
1120            ensureLock(res);
1121            CmsFile file = cms.readFile(res);
1122            String oldLink = new String(file.getContents(), CmsLocaleManager.getResourceEncoding(cms, res));
1123            if (!oldLink.equals(link)) {
1124                file.setContents(link.getBytes(CmsLocaleManager.getResourceEncoding(cms, res)));
1125                cms.writeFile(file);
1126            }
1127            CmsProperty titleProp = cms.readPropertyObject(res, CmsPropertyDefinition.PROPERTY_TITLE, false);
1128            if (titleProp.isNullProperty()) {
1129                titleProp = new CmsProperty(CmsPropertyDefinition.PROPERTY_TITLE, title, null);
1130                cms.writePropertyObject(cms.getSitePath(res), titleProp);
1131            } else if (!titleProp.getValue().equals(title)) {
1132                titleProp.setStructureValue(title);
1133                cms.writePropertyObject(cms.getSitePath(res), titleProp);
1134            }
1135            if (!res.getName().equals(fileName)) {
1136                String oldSitePath = cms.getSitePath(res);
1137                String newSitePath = CmsStringUtil.joinPaths(CmsResource.getParentFolder(oldSitePath), fileName);
1138                getCmsObject().renameResource(oldSitePath, newSitePath);
1139            }
1140            tryUnlock(res);
1141            // update the offline search indices
1142            OpenCms.getSearchManager().updateOfflineIndexes();
1143        } catch (Exception e) {
1144            error(e);
1145        }
1146    }
1147
1148    /**
1149     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#saveProperties(org.opencms.gwt.shared.property.CmsPropertyChangeSet, boolean)
1150     */
1151    public void saveProperties(CmsPropertyChangeSet changes, boolean updateIndex) throws CmsRpcException {
1152
1153        String origSiteRoot = getCmsObject().getRequestContext().getSiteRoot();
1154        try {
1155            getCmsObject().getRequestContext().setSiteRoot("");
1156            CmsPropertyEditorHelper helper = new CmsPropertyEditorHelper(getCmsObject());
1157            helper.setUpdateIndex(updateIndex);
1158            helper.saveProperties(changes);
1159        } catch (Throwable t) {
1160            error(t);
1161        } finally {
1162            getCmsObject().getRequestContext().setSiteRoot(origSiteRoot);
1163        }
1164    }
1165
1166    /**
1167     * Sets the current cms context.<p>
1168     *
1169     * @param cms the current cms context to set
1170     */
1171    @Override
1172    public synchronized void setCms(CmsObject cms) {
1173
1174        super.setCms(cms);
1175        m_aliasHelper.setCms(cms);
1176    }
1177
1178    /**
1179     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#substituteLinkForRootPath(java.lang.String, java.lang.String)
1180     */
1181    public String substituteLinkForRootPath(String currentSiteRoot, String rootPath) throws CmsRpcException {
1182
1183        String result = null;
1184        try {
1185            CmsObject cms = OpenCms.initCmsObject(getCmsObject());
1186            cms.getRequestContext().setSiteRoot(currentSiteRoot);
1187            result = OpenCms.getLinkManager().substituteLinkForRootPath(cms, rootPath);
1188        } catch (CmsException e) {
1189            error(e);
1190        }
1191        return result;
1192    }
1193
1194    /**
1195     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#syncDeleteResource(org.opencms.util.CmsUUID)
1196     */
1197    public void syncDeleteResource(CmsUUID structureId) throws CmsRpcException {
1198
1199        deleteResource(structureId);
1200    }
1201
1202    /**
1203     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#undelete(org.opencms.util.CmsUUID)
1204     */
1205    public void undelete(CmsUUID structureId) throws CmsRpcException {
1206
1207        try {
1208            CmsObject cms = OpenCms.initCmsObject(getCmsObject());
1209            cms.getRequestContext().setSiteRoot("");
1210            CmsResource resource = cms.readResource(structureId, CmsResourceFilter.ALL);
1211            ensureLock(resource);
1212            cms.undeleteResource(resource.getRootPath(), true);
1213        } catch (Exception e) {
1214            error(e);
1215        }
1216    }
1217
1218    /**
1219     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#undoChanges(org.opencms.util.CmsUUID, boolean)
1220     */
1221    public void undoChanges(CmsUUID structureId, boolean undoMove) throws CmsRpcException {
1222
1223        try {
1224            CmsObject cms = getCmsObject();
1225            CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
1226            ensureLock(resource);
1227            CmsResourceUndoMode mode = undoMove ? CmsResource.UNDO_MOVE_CONTENT : CmsResource.UNDO_CONTENT;
1228            String path = cms.getSitePath(resource);
1229            cms.undoChanges(path, mode);
1230            try {
1231                resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
1232                path = cms.getSitePath(resource);
1233                cms.unlockResource(path);
1234            } catch (CmsException e) {
1235                LOG.info("Could not unlock resource after undoing changes: " + e.getLocalizedMessage(), e);
1236            }
1237        } catch (Throwable e) {
1238            error(e);
1239        }
1240    }
1241
1242    /**
1243     * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#validateAliases(org.opencms.util.CmsUUID, java.util.Map)
1244     */
1245    public Map<String, String> validateAliases(CmsUUID uuid, Map<String, String> aliasPaths) throws CmsRpcException {
1246
1247        try {
1248            return m_aliasHelper.validateAliases(uuid, aliasPaths);
1249        } catch (Throwable e) {
1250            error(e);
1251        }
1252        return null;
1253
1254    }
1255
1256    /**
1257     * Creates a "broken link" bean based on a resource.<p>
1258     *
1259     * @param resource the resource
1260     *
1261     * @return the "broken link" bean with the data from the resource
1262     *
1263     * @throws CmsException if something goes wrong
1264     */
1265    protected CmsBrokenLinkBean createSitemapBrokenLinkBean(CmsResource resource) throws CmsException {
1266
1267        CmsObject cms = getCmsObject();
1268        CmsProperty titleProp = cms.readPropertyObject(resource, CmsPropertyDefinition.PROPERTY_TITLE, true);
1269        String typeName = OpenCms.getResourceManager().getResourceType(resource).getTypeName();
1270        String defaultTitle = "";
1271        String title = titleProp.getValue(defaultTitle);
1272        String path = cms.getSitePath(resource);
1273        String subtitle = path;
1274        String icon = CmsIconUtil.getIconClasses(CmsIconUtil.getDisplayType(cms, resource), resource.getName(), false);
1275
1276        CmsBrokenLinkBean result = new CmsBrokenLinkBean(resource.getStructureId(), title, subtitle, typeName, icon);
1277
1278        return result;
1279    }
1280
1281    /**
1282     * Helper method for creating a VFS entry bean from a resource.<p>
1283     *
1284     * @param resource the resource whose data should be stored in the bean
1285     * @param root true if the resource is a root resource
1286     *
1287     * @return the data bean representing the resource
1288     *
1289     * @throws CmsException if something goes wrong
1290     */
1291    protected CmsVfsEntryBean makeEntryBean(CmsResource resource, boolean root) throws CmsException {
1292
1293        CmsObject cms = getCmsObject();
1294        boolean isFolder = resource.isFolder();
1295        String name = root ? "/" : resource.getName();
1296        String path = cms.getSitePath(resource);
1297        boolean hasChildren = false;
1298        if (isFolder) {
1299            List<CmsResource> children = cms.getResourcesInFolder(
1300                cms.getRequestContext().getSitePath(resource),
1301                CmsResourceFilter.DEFAULT);
1302            if (!children.isEmpty()) {
1303                hasChildren = true;
1304            }
1305        }
1306        String resourceType = OpenCms.getResourceManager().getResourceType(resource.getTypeId()).getTypeName();
1307
1308        return new CmsVfsEntryBean(path, name, resourceType, isFolder, hasChildren);
1309    }
1310
1311    /**
1312     * Helper method for creating a list of VFS entry beans from a list of the corresponding resources.<p>
1313     *
1314     * @param resources the list of resources which should be converted to entry beans
1315     * @param root true if the resources in the list are root resources
1316     *
1317     * @return the list of VFS entry beans for the resources
1318     *
1319     * @throws CmsException if something goes wrong
1320     */
1321    protected List<CmsVfsEntryBean> makeEntryBeans(List<CmsResource> resources, boolean root) throws CmsException {
1322
1323        List<CmsVfsEntryBean> result = new ArrayList<CmsVfsEntryBean>();
1324        for (CmsResource res : resources) {
1325            result.add(makeEntryBean(res, root));
1326        }
1327        return result;
1328    }
1329
1330    /**
1331     * Adds additional info items for broken links.<p>
1332     *
1333     * @param cms the CMS context to use
1334     * @param resource the resource from which the additional infos should be read
1335     * @param result the result in which to store the additional info
1336     */
1337    private void addBrokenLinkAdditionalInfo(CmsObject cms, CmsResource resource, CmsBrokenLinkBean result) {
1338
1339        String dateLastModifiedLabel = org.opencms.workplace.commons.Messages.get().getBundle(
1340            OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key(
1341                org.opencms.workplace.commons.Messages.GUI_LABEL_DATE_LAST_MODIFIED_0);
1342        String dateLastModified = CmsVfsService.formatDateTime(cms, resource.getDateLastModified());
1343
1344        String userLastModifiedLabel = org.opencms.workplace.commons.Messages.get().getBundle(
1345            OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key(
1346                org.opencms.workplace.commons.Messages.GUI_LABEL_USER_LAST_MODIFIED_0);
1347        String userLastModified = "" + resource.getUserLastModified();
1348        try {
1349            userLastModified = cms.readUser(resource.getUserLastModified()).getName();
1350        } catch (CmsException e) {
1351            LOG.error(e.getLocalizedMessage(), e);
1352        }
1353
1354        result.addInfo(dateLastModifiedLabel, dateLastModified);
1355        result.addInfo(userLastModifiedLabel, userLastModified);
1356    }
1357
1358    /**
1359     * Creates a bean representing a historical resource version.<p>
1360     *
1361     * @param cms the current CMS context
1362     * @param historyRes the historical resource
1363     * @param offline true if this resource was read from the offline project
1364     * @param maxVersion the largest version number found
1365     *
1366     * @return the bean representing the historical resource
1367     * @throws CmsException if something goes wrong
1368     */
1369    private CmsHistoryResourceBean createHistoryResourceBean(
1370        CmsObject cms,
1371        CmsResource historyRes,
1372        boolean offline,
1373        int maxVersion)
1374    throws CmsException {
1375
1376        CmsHistoryResourceBean result = new CmsHistoryResourceBean();
1377
1378        Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms);
1379        result.setStructureId(historyRes.getStructureId());
1380        result.setRootPath(historyRes.getRootPath());
1381        result.setDateLastModified(formatDate(historyRes.getDateLastModified(), locale));
1382        CmsUUID userId = historyRes.getUserLastModified();
1383        String userName = userId.toString();
1384        try {
1385            CmsUser user = cms.readUser(userId);
1386            userName = user.getName();
1387        } catch (CmsException e) {
1388            LOG.warn(e.getLocalizedMessage(), e);
1389        }
1390        result.setUserLastModified(userName);
1391        result.setSize(historyRes.getLength());
1392        if (historyRes instanceof I_CmsHistoryResource) {
1393            int publishTag = ((I_CmsHistoryResource)historyRes).getPublishTag();
1394            CmsHistoryProject project = cms.readHistoryProject(publishTag);
1395            long publishDate = project.getPublishingDate();
1396            result.setDatePublished(formatDate(publishDate, locale));
1397            int version = ((I_CmsHistoryResource)historyRes).getVersion();
1398            result.setVersion(
1399                new CmsHistoryVersion(
1400                    Integer.valueOf(historyRes.getVersion()),
1401                    maxVersion == version ? OfflineOnline.online : null));
1402
1403            List<CmsProperty> historyProperties = cms.readHistoryPropertyObjects((I_CmsHistoryResource)historyRes);
1404            Map<String, CmsProperty> historyPropertyMap = CmsProperty.toObjectMap(historyProperties);
1405            CmsProperty titleProp = CmsProperty.wrapIfNull(
1406                historyPropertyMap.get(CmsPropertyDefinition.PROPERTY_TITLE));
1407            CmsProperty descProp = CmsProperty.wrapIfNull(
1408                historyPropertyMap.get(CmsPropertyDefinition.PROPERTY_DESCRIPTION));
1409            result.setTitle(titleProp.getValue());
1410            result.setDescription(descProp.getValue());
1411        } else {
1412            if (offline) {
1413                result.setVersion(new CmsHistoryVersion(null, OfflineOnline.offline));
1414            } else {
1415                result.setVersion(new CmsHistoryVersion(null, OfflineOnline.online));
1416            }
1417        }
1418        return result;
1419    }
1420
1421    /**
1422     * Internal method to delete the given resource.<p>
1423     *
1424     * @param resource the resource to delete
1425     *
1426     * @throws CmsException if something goes wrong
1427     */
1428    private void deleteResource(CmsResource resource) throws CmsException {
1429
1430        String path = null;
1431        CmsObject cms = getCmsObject();
1432        try {
1433            path = cms.getSitePath(resource);
1434            cms.lockResource(path);
1435            cms.deleteResource(path, CmsResource.DELETE_PRESERVE_SIBLINGS);
1436            // check if any detail container page resources exist to this resource
1437            List<CmsResource> detailContainers = CmsDetailOnlyContainerUtil.getDetailOnlyResources(cms, resource);
1438            for (CmsResource detailContainer : detailContainers) {
1439                deleteResource(detailContainer);
1440            }
1441        } finally {
1442            try {
1443                if (path != null) {
1444                    getCmsObject().unlockResource(path);
1445                }
1446            } catch (Exception e) {
1447                // should really never happen
1448                LOG.debug(e.getLocalizedMessage(), e);
1449            }
1450        }
1451    }
1452
1453    /**
1454     * Converts a date to a date bean.<p>
1455     *
1456     * @param date the date to convert
1457     * @param locale the locale to use for the conversion
1458     *
1459     * @return the date bean
1460     */
1461    private CmsClientDateBean formatDate(long date, Locale locale) {
1462
1463        return new CmsClientDateBean(date, formatDateTime(date));
1464    }
1465
1466    /**
1467     * Formats the date for the current user's locale.<p>
1468     *
1469     * @param date the date to format
1470     *
1471     * @return the formatted date for the current user's locale
1472     */
1473    private String formatDateTime(long date) {
1474
1475        CmsObject cms = getCmsObject();
1476        return formatDateTime(cms, date);
1477    }
1478
1479    /**
1480     * Returns the available locales mapped to there display name for the given resource
1481     * or <code>null</code> in case of non xml-content/xml-page resources.<p>
1482     *
1483     * @param resource the resource
1484     *
1485     * @return the available locales
1486     */
1487    private LinkedHashMap<String, String> getAvailableLocales(CmsResource resource) {
1488
1489        LinkedHashMap<String, String> result = null;
1490        List<Locale> locales = null;
1491        try {
1492            if (CmsResourceTypeXmlPage.isXmlPage(resource)) {
1493                locales = CmsXmlPageFactory.unmarshal(getCmsObject(), resource, getRequest()).getLocales();
1494            } else if (CmsResourceTypeXmlContent.isXmlContent(resource)) {
1495                locales = CmsXmlContentFactory.unmarshal(getCmsObject(), resource, getRequest()).getLocales();
1496            } else if (CmsResourceTypeXmlContainerPage.isContainerPage(resource)) {
1497                locales = CmsXmlContainerPageFactory.unmarshal(getCmsObject(), resource).getLocales();
1498            }
1499        } catch (CmsException e) {
1500            LOG.warn(e.getLocalizedMessage(), e);
1501        }
1502        if (locales != null) {
1503            Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject());
1504            result = new LinkedHashMap<String, String>();
1505            for (Locale locale : locales) {
1506                result.put(locale.toString(), locale.getDisplayName(wpLocale));
1507            }
1508        }
1509        return result;
1510    }
1511
1512    /**
1513     * Helper method for converting a map which maps resources to resources to a list of "broken link" beans,
1514     * which have beans representing the source of the corresponding link as children.<p>
1515     *
1516     * @param linkMap a multimap from resource to resources
1517     *
1518     * @return a list of beans representing links which will be broken
1519     *
1520     * @throws CmsException if something goes wrong
1521     */
1522    private List<CmsBrokenLinkBean> getBrokenLinkBeans(Multimap<CmsResource, CmsResource> linkMap) throws CmsException {
1523
1524        CmsBrokenLinkRenderer brokenLinkRenderer = new CmsBrokenLinkRenderer(getCmsObject());
1525
1526        Multimap<CmsBrokenLinkBean, CmsBrokenLinkBean> resultMap = HashMultimap.create();
1527
1528        for (CmsResource source : linkMap.keySet()) {
1529
1530            for (CmsResource target : linkMap.get(source)) {
1531                CmsBrokenLinkBean targetBean = createSitemapBrokenLinkBean(target);
1532                addBrokenLinkAdditionalInfo(getCmsObject(), target, targetBean);
1533                List<CmsBrokenLinkBean> brokenLinkBeans = brokenLinkRenderer.renderBrokenLink(target, source);
1534                for (CmsBrokenLinkBean childBean : brokenLinkBeans) {
1535                    addBrokenLinkAdditionalInfo(getCmsObject(), source, childBean);
1536                    resultMap.put(childBean, targetBean);
1537                }
1538            }
1539        }
1540
1541        // now convert multimap representation to parent/child representation
1542        for (CmsBrokenLinkBean parent : resultMap.keySet()) {
1543            for (CmsBrokenLinkBean child : resultMap.get(parent)) {
1544                parent.addChild(child);
1545            }
1546        }
1547        return Lists.newArrayList(resultMap.keySet());
1548    }
1549
1550    /**
1551     * Internal method to get the broken links information for the given resource.<p>
1552     *
1553     * @param entryResource the resource
1554     *
1555     * @return the broken links information
1556     *
1557     * @throws CmsException if something goes wrong
1558     */
1559    private CmsDeleteResourceBean getBrokenLinks(CmsResource entryResource) throws CmsException {
1560
1561        CmsDeleteResourceBean result = null;
1562
1563        CmsListInfoBean info = null;
1564        List<CmsBrokenLinkBean> brokenLinks = null;
1565
1566        CmsObject cms = getCmsObject();
1567        String resourceSitePath = cms.getSitePath(entryResource);
1568
1569        ensureSession();
1570
1571        List<CmsResource> descendants = new ArrayList<CmsResource>();
1572        HashSet<CmsUUID> deleteIds = new HashSet<CmsUUID>();
1573
1574        descendants.add(entryResource);
1575        if (entryResource.isFolder()) {
1576            descendants.addAll(cms.readResources(resourceSitePath, CmsResourceFilter.IGNORE_EXPIRATION));
1577        }
1578
1579        for (CmsResource deleteRes : descendants) {
1580            deleteIds.add(deleteRes.getStructureId());
1581        }
1582        Multimap<CmsResource, CmsResource> linkMap = HashMultimap.create();
1583        for (CmsResource resource : descendants) {
1584            List<CmsRelation> relations = cms.getRelationsForResource(resource, CmsRelationFilter.SOURCES);
1585            List<CmsResource> result1 = new ArrayList<CmsResource>();
1586            for (CmsRelation relation : relations) {
1587                // only add related resources that are not going to be deleted
1588                if (!deleteIds.contains(relation.getSourceId())) {
1589                    CmsResource source1 = relation.getSource(cms, CmsResourceFilter.ALL);
1590                    if (!source1.getState().isDeleted()) {
1591                        result1.add(source1);
1592                    }
1593                }
1594            }
1595            List<CmsResource> linkSources = result1;
1596            for (CmsResource source : linkSources) {
1597                linkMap.put(source, resource);
1598            }
1599        }
1600
1601        brokenLinks = getBrokenLinkBeans(linkMap);
1602        info = getPageInfo(entryResource);
1603
1604        result = new CmsDeleteResourceBean(resourceSitePath, info, brokenLinks);
1605
1606        return result;
1607    }
1608
1609    /**
1610     * Gets the resources which link to a given structure id.<p>
1611     *
1612     * @param cms the current CMS context
1613     * @param resource the relation target resource
1614     * @param deleteIds set of resources to delete
1615     *
1616     * @return the list of resources which link to the given id
1617     *
1618     * @throws CmsException if something goes wrong
1619     */
1620    @SuppressWarnings("unused")
1621    private List<CmsResource> getLinkSources(CmsObject cms, CmsResource resource, HashSet<CmsUUID> deleteIds)
1622    throws CmsException {
1623
1624        List<CmsRelation> relations = cms.getRelationsForResource(resource, CmsRelationFilter.SOURCES);
1625        List<CmsResource> result = new ArrayList<CmsResource>();
1626        for (CmsRelation relation : relations) {
1627            // only add related resources that are not going to be deleted
1628            if (!deleteIds.contains(relation.getSourceId())) {
1629                CmsResource source = relation.getSource(cms, CmsResourceFilter.ALL);
1630                if (!source.getState().isDeleted()) {
1631                    result.add(source);
1632                }
1633            }
1634        }
1635        return result;
1636    }
1637
1638    /**
1639     * Returns a bean to display the {@link org.opencms.gwt.client.ui.CmsListItemWidget}.<p>
1640     *
1641     * @param res the resource to get the page info for
1642     *
1643     * @return a bean to display the {@link org.opencms.gwt.client.ui.CmsListItemWidget}.<p>
1644     *
1645     * @throws CmsLoaderException if the resource type could not be found
1646     * @throws CmsException if something else goes wrong
1647     */
1648    private CmsListInfoBean getPageInfo(CmsResource res) throws CmsException, CmsLoaderException {
1649
1650        CmsObject cms = getCmsObject();
1651        return getPageInfo(cms, res);
1652    }
1653
1654    /**
1655     * Returns the preview info for the given resource.<p>
1656     *
1657     *@param cms the CMS context
1658     * @param resource the resource
1659     * @param locale the requested locale
1660     *
1661     * @return the preview info
1662     */
1663    private CmsPreviewInfo getPreviewInfo(CmsObject cms, CmsResource resource, Locale locale) {
1664
1665        String title = "";
1666        try {
1667            CmsProperty titleProperty = cms.readPropertyObject(resource, CmsPropertyDefinition.PROPERTY_TITLE, false);
1668            title = titleProperty.getValue("");
1669        } catch (CmsException e) {
1670            LOG.warn(e.getLocalizedMessage(), e);
1671        }
1672        String noPreviewReason = getNoPreviewReason(cms, resource);
1673        String previewContent = null;
1674        int height = 0;
1675        int width = 0;
1676        LinkedHashMap<String, String> locales = getAvailableLocales(resource);
1677        if (noPreviewReason != null) {
1678            previewContent = "<div>" + noPreviewReason + "</div>";
1679            return new CmsPreviewInfo(
1680                "<div>" + noPreviewReason + "</div>",
1681                null,
1682                false,
1683                title,
1684                cms.getSitePath(resource),
1685                locale.toString());
1686        } else if (OpenCms.getResourceManager().matchResourceType(
1687            CmsResourceTypeImage.getStaticTypeName(),
1688            resource.getTypeId())) {
1689                CmsImageScaler scaler = new CmsImageScaler(cms, resource);
1690                String imageLink = null;
1691                if (resource instanceof I_CmsHistoryResource) {
1692                    int version = ((I_CmsHistoryResource)resource).getVersion();
1693                    imageLink = OpenCms.getLinkManager().substituteLinkForUnknownTarget(
1694                        cms,
1695                        CmsHistoryListUtil.getHistoryLink(cms, resource.getStructureId(), "" + version));
1696                } else {
1697                    imageLink = OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, resource.getRootPath());
1698                }
1699                imageLink = CmsRequestUtil.appendParameter(imageLink, "random", "" + Math.random());
1700                previewContent = "<img src=\"" + imageLink + "\" title=\"" + title + "\" style=\"display:block\" />";
1701                height = scaler.getHeight();
1702                width = scaler.getWidth();
1703            } else if (isContainerOrXmlPage(resource)) {
1704                String link = "";
1705                if (resource instanceof I_CmsHistoryResource) {
1706                    int version = ((I_CmsHistoryResource)resource).getVersion();
1707                    link = OpenCms.getLinkManager().substituteLinkForUnknownTarget(
1708                        cms,
1709                        CmsHistoryListUtil.getHistoryLink(cms, resource.getStructureId(), "" + version));
1710                } else {
1711                    link = OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, resource.getRootPath());
1712                }
1713                return new CmsPreviewInfo(null, link, true, null, cms.getSitePath(resource), locale.toString());
1714            } else if (isBinary(resource)) {
1715                String link = "";
1716                if (resource instanceof I_CmsHistoryResource) {
1717                    int version = ((I_CmsHistoryResource)resource).getVersion();
1718                    link = OpenCms.getLinkManager().substituteLinkForUnknownTarget(
1719                        cms,
1720                        CmsHistoryListUtil.getHistoryLink(cms, resource.getStructureId(), "" + version));
1721                } else {
1722                    link = OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, resource.getRootPath());
1723                }
1724                return new CmsPreviewInfo(null, link, true, null, cms.getSitePath(resource), locale.toString());
1725            } else if (CmsResourceTypeXmlContent.isXmlContent(resource)) {
1726                if (!locales.containsKey(locale.toString())) {
1727                    locale = CmsLocaleManager.getMainLocale(cms, resource);
1728                }
1729                previewContent = CmsPreviewService.getPreviewContent(
1730                    getRequest(),
1731                    getResponse(),
1732                    cms,
1733                    resource,
1734                    locale);
1735
1736            } else if (CmsResourceTypePlain.getStaticTypeId() == resource.getTypeId()) {
1737                try {
1738                    previewContent = "<pre><code>" + new String(cms.readFile(resource).getContents()) + "</code></pre>";
1739                } catch (CmsException e) {
1740                    LOG.warn(e.getLocalizedMessage(), e);
1741                    previewContent = "<div>"
1742                        + Messages.get().getBundle(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key(
1743                            Messages.GUI_NO_PREVIEW_CAN_T_READ_CONTENT_0)
1744                        + "</div>";
1745                }
1746            }
1747        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(previewContent)) {
1748            CmsPreviewInfo result = new CmsPreviewInfo(
1749                previewContent,
1750                null,
1751                false,
1752                title,
1753                cms.getSitePath(resource),
1754                locale.toString());
1755            result.setHeight(height);
1756            result.setWidth(width);
1757            result.setLocales(locales);
1758            return result;
1759        }
1760        if (isContainerOrXmlPage(resource)) {
1761            CmsPreviewInfo result = new CmsPreviewInfo(
1762                null,
1763                OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, resource.getRootPath())
1764                    + "?"
1765                    + CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT
1766                    + "=true"
1767                    + "&__locale="
1768                    + locale.toString(),
1769                false,
1770                title,
1771                cms.getSitePath(resource),
1772                locale.toString());
1773            result.setLocales(locales);
1774            return result;
1775        }
1776        return new CmsPreviewInfo(
1777            null,
1778            OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, resource.getRootPath())
1779                + "?"
1780                + CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT
1781                + "=true",
1782            true,
1783            title,
1784            cms.getSitePath(resource),
1785            locale.toString());
1786    }
1787
1788    /**
1789     * Checks if resource has the type 'binary'.
1790     *
1791     * @param resource the resource
1792     * @return true if the resource is a binary file
1793     */
1794    private boolean isBinary(CmsResource resource) {
1795
1796        return OpenCms.getResourceManager().matchResourceType(
1797            CmsResourceTypeBinary.getStaticTypeName(),
1798            resource.getTypeId());
1799    }
1800
1801    /**
1802     * Checks if resource is a container page or xml page.
1803     *
1804     * @param resource the resource to check
1805     * @return true if the resource is a container page or XML page
1806     */
1807    private boolean isContainerOrXmlPage(CmsResource resource) {
1808
1809        return CmsResourceTypeXmlContainerPage.isContainerPage(resource) || CmsResourceTypeXmlPage.isXmlPage(resource);
1810    }
1811
1812}