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.db.CmsResourceState;
031import org.opencms.file.CmsObject;
032import org.opencms.file.CmsProject;
033import org.opencms.file.CmsPropertyDefinition;
034import org.opencms.file.CmsResource;
035import org.opencms.file.CmsResourceFilter;
036import org.opencms.file.CmsUser;
037import org.opencms.file.CmsVfsResourceNotFoundException;
038import org.opencms.flex.CmsFlexController;
039import org.opencms.gwt.shared.CmsBroadcastMessage;
040import org.opencms.gwt.shared.CmsCategoryTreeEntry;
041import org.opencms.gwt.shared.CmsContextMenuEntryBean;
042import org.opencms.gwt.shared.CmsCoreData;
043import org.opencms.gwt.shared.CmsCoreData.AdeContext;
044import org.opencms.gwt.shared.CmsCoreData.UserInfo;
045import org.opencms.gwt.shared.CmsLockInfo;
046import org.opencms.gwt.shared.CmsResourceCategoryInfo;
047import org.opencms.gwt.shared.CmsReturnLinkInfo;
048import org.opencms.gwt.shared.CmsTinyMCEData;
049import org.opencms.gwt.shared.CmsUserSettingsBean;
050import org.opencms.gwt.shared.CmsValidationQuery;
051import org.opencms.gwt.shared.CmsValidationResult;
052import org.opencms.gwt.shared.rpc.I_CmsCoreService;
053import org.opencms.i18n.CmsMessages;
054import org.opencms.lock.CmsLock;
055import org.opencms.main.CmsBroadcast;
056import org.opencms.main.CmsException;
057import org.opencms.main.CmsIllegalArgumentException;
058import org.opencms.main.CmsLog;
059import org.opencms.main.CmsSessionInfo;
060import org.opencms.main.OpenCms;
061import org.opencms.module.CmsModule;
062import org.opencms.relations.CmsCategory;
063import org.opencms.relations.CmsCategoryService;
064import org.opencms.security.CmsPasswordInfo;
065import org.opencms.security.CmsRole;
066import org.opencms.security.CmsRoleManager;
067import org.opencms.security.CmsSecurityException;
068import org.opencms.site.CmsSite;
069import org.opencms.ui.CmsUserIconHelper;
070import org.opencms.ui.CmsVaadinUtils;
071import org.opencms.ui.I_CmsDialogContext;
072import org.opencms.ui.I_CmsDialogContextWithAdeContext;
073import org.opencms.ui.actions.I_CmsADEAction;
074import org.opencms.ui.apps.CmsFileExplorerConfiguration;
075import org.opencms.ui.components.CmsBasicDialog.DialogWidth;
076import org.opencms.ui.contextmenu.CmsMenuItemVisibilityMode;
077import org.opencms.ui.contextmenu.I_CmsContextMenuItem;
078import org.opencms.ui.dialogs.CmsEmbeddedDialogsUI;
079import org.opencms.util.CmsFileUtil;
080import org.opencms.util.CmsStringUtil;
081import org.opencms.util.CmsUUID;
082import org.opencms.workplace.CmsWorkplace;
083import org.opencms.workplace.CmsWorkplaceLoginHandler;
084import org.opencms.xml.containerpage.CmsADESessionCache;
085
086import java.util.ArrayList;
087import java.util.Collection;
088import java.util.Collections;
089import java.util.Comparator;
090import java.util.HashMap;
091import java.util.HashSet;
092import java.util.LinkedHashMap;
093import java.util.List;
094import java.util.Locale;
095import java.util.Map;
096import java.util.Map.Entry;
097import java.util.Set;
098
099import javax.servlet.http.HttpServletRequest;
100
101import org.apache.commons.collections.Buffer;
102import org.apache.commons.logging.Log;
103
104import com.vaadin.ui.Component;
105import com.vaadin.ui.Window;
106
107/**
108 * Provides general core services.<p>
109 *
110 * @since 8.0.0
111 *
112 * @see org.opencms.gwt.CmsCoreService
113 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService
114 * @see org.opencms.gwt.shared.rpc.I_CmsCoreServiceAsync
115 */
116public class CmsCoreService extends CmsGwtService implements I_CmsCoreService {
117
118    /** The editor back-link URI. */
119    private static final String EDITOR_BACKLINK_URI = "/system/workplace/commons/editor-backlink.html";
120
121    /** The xml-content editor URI. */
122    private static final String EDITOR_URI = "/system/workplace/editors/editor.jsp";
123
124    /** The log instance for this class. */
125    private static final Log LOG = CmsLog.getLog(CmsCoreService.class);
126
127    /** Serialization uid. */
128    private static final long serialVersionUID = 5915848952948986278L;
129
130    /**
131     * Builds the tree structure for the given categories.<p>
132     *
133     * @param cms the current cms context
134     * @param categories the categories
135     *
136     * @return the tree root element
137     */
138    public static List<CmsCategoryTreeEntry> buildCategoryTree(CmsObject cms, List<CmsCategory> categories) {
139
140        List<CmsCategoryTreeEntry> result = new ArrayList<CmsCategoryTreeEntry>();
141        for (CmsCategory category : categories) {
142            CmsCategoryTreeEntry current = new CmsCategoryTreeEntry(category);
143            current.setSitePath(cms.getRequestContext().removeSiteRoot(category.getRootPath()));
144            String parentPath = CmsResource.getParentFolder(current.getPath());
145            CmsCategoryTreeEntry parent = null;
146            parent = findCategory(result, parentPath);
147            if (parent != null) {
148                parent.addChild(current);
149            } else {
150                result.add(current);
151            }
152        }
153        return result;
154    }
155
156    /**
157     * Helper method for getting the category beans for the given site path.<p>
158     *
159     * @param cms the CMS context to use
160     * @param sitePath the site path
161     * @return the list of category beans
162     *
163     * @throws CmsException if something goes wrong
164     */
165    public static List<CmsCategoryTreeEntry> getCategoriesForSitePathStatic(CmsObject cms, String sitePath)
166    throws CmsException {
167
168        return getCategoriesForSitePathStatic(cms, sitePath, null);
169    }
170
171    /**
172     * Helper method for getting the category beans for the given site path.<p>
173     *
174     * @param cms the CMS context to use
175     * @param sitePath the site path
176     * @param localCategoryRepositoryPath the categories for this repository are added separately
177     * @return the list of category beans
178     *
179     * @throws CmsException if something goes wrong
180     */
181    public static List<CmsCategoryTreeEntry> getCategoriesForSitePathStatic(
182        CmsObject cms,
183        String sitePath,
184        String localCategoryRepositoryPath)
185    throws CmsException {
186
187        List<CmsCategoryTreeEntry> result;
188        CmsCategoryService catService = CmsCategoryService.getInstance();
189        List<CmsCategory> categories;
190        Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms);
191        // get the categories
192        if (null == localCategoryRepositoryPath) {
193            categories = catService.readCategories(cms, "", true, sitePath);
194            categories = catService.localizeCategories(cms, categories, wpLocale);
195            result = buildCategoryTree(cms, categories);
196        } else {
197            List<String> repositories = catService.getCategoryRepositories(cms, sitePath);
198            repositories.remove(localCategoryRepositoryPath);
199            categories = catService.readCategoriesForRepositories(cms, "", true, repositories);
200            categories = catService.localizeCategories(cms, categories, wpLocale);
201            result = buildCategoryTree(cms, categories);
202            categories = catService.readCategoriesForRepositories(
203                cms,
204                "",
205                true,
206                Collections.singletonList(localCategoryRepositoryPath));
207            categories = catService.localizeCategories(cms, categories, wpLocale);
208            List<CmsCategoryTreeEntry> localCategories = buildCategoryTree(cms, categories);
209            result.addAll(localCategories);
210        }
211
212        return result;
213    }
214
215    /**
216     * Returns the context menu entries for the given URI.<p>
217     *
218     * @param cms the cms context
219     * @param structureId the currently requested structure id
220     * @param context the ade context (sitemap or containerpage)
221     *
222     * @return the context menu entries
223     */
224    public static List<CmsContextMenuEntryBean> getContextMenuEntries(
225        final CmsObject cms,
226        CmsUUID structureId,
227        final AdeContext context) {
228
229        Map<String, CmsContextMenuEntryBean> entries = new LinkedHashMap<String, CmsContextMenuEntryBean>();
230        try {
231            final List<CmsResource> resources;
232            CmsResource resource = cms.readResource(structureId, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED);
233            // in case of sitemap editor check visibility with empty list
234            if (context.equals(AdeContext.sitemapeditor)) {
235                resources = Collections.emptyList();
236            } else {
237                resources = Collections.singletonList(resource);
238            }
239            Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms);
240            // context to check item visibility
241            I_CmsDialogContext dcontext = new I_CmsDialogContextWithAdeContext() {
242
243                public void error(Throwable error) {
244                    // not supported
245                }
246
247                public void finish(CmsProject project, String siteRoot) {
248                    // not supported
249                }
250
251                public void finish(Collection<CmsUUID> result) {
252                    // not supported
253                }
254
255                public void focus(CmsUUID id) {
256                    // not supported
257                }
258
259                public AdeContext getAdeContext() {
260
261                    return context;
262                }
263
264                public List<CmsUUID> getAllStructureIdsInView() {
265
266                    return null;
267                }
268
269                public String getAppId() {
270
271                    return context.name();
272                }
273
274                public CmsObject getCms() {
275
276                    return cms;
277                }
278
279                public ContextType getContextType() {
280
281                    ContextType type;
282                    switch (context) {
283                        case pageeditor:
284                        case editprovider:
285                            type = ContextType.containerpageToolbar;
286                            break;
287                        case sitemapeditor:
288                            type = ContextType.sitemapToolbar;
289                            break;
290                        default:
291                            type = ContextType.fileTable;
292                    }
293                    return type;
294                }
295
296                public List<CmsResource> getResources() {
297
298                    return resources;
299                }
300
301                public void navigateTo(String appId) {
302                    // not supported
303                }
304
305                public void onViewChange() {
306                    // not supported
307                }
308
309                public void reload() {
310                    // not supported
311                }
312
313                public void setWindow(Window window) {
314                    // not supported
315                }
316
317                public void start(String title, Component dialog) {
318                    // not supported
319                }
320
321                public void start(String title, Component dialog, DialogWidth width) {
322                    // not supported
323                }
324
325                public void updateUserInfo() {
326                    // not supported
327                }
328            };
329            Map<String, List<CmsContextMenuEntryBean>> submenus = new HashMap<String, List<CmsContextMenuEntryBean>>();
330            List<I_CmsContextMenuItem> items = new ArrayList<I_CmsContextMenuItem>(
331                OpenCms.getWorkplaceAppManager().getMenuItemProvider().getMenuItems());
332            Collections.sort(items, new Comparator<I_CmsContextMenuItem>() {
333
334                public int compare(I_CmsContextMenuItem arg0, I_CmsContextMenuItem arg1) {
335
336                    return Float.compare(arg0.getOrder(), arg1.getOrder());
337                }
338            });
339
340            for (I_CmsContextMenuItem item : items) {
341
342                if (!item.isLeafItem()) {
343                    CmsMenuItemVisibilityMode visibility = item.getVisibility(dcontext);
344                    if (!visibility.isInVisible()) {
345                        entries.put(
346                            item.getId(),
347                            new CmsContextMenuEntryBean(
348                                visibility.isActive(),
349                                true,
350                                null,
351                                item.getTitle(locale),
352                                null,
353                                CmsStringUtil.isEmptyOrWhitespaceOnly(visibility.getMessageKey())
354                                ? null
355                                : OpenCms.getWorkplaceManager().getMessages(locale).getString(
356                                    visibility.getMessageKey()),
357                                false,
358                                new ArrayList<CmsContextMenuEntryBean>()));
359                    }
360                } else if ((item instanceof I_CmsADEAction) && ((I_CmsADEAction)item).isAdeSupported()) {
361                    CmsMenuItemVisibilityMode visibility = item.getVisibility(dcontext);
362                    if (!visibility.isInVisible()) {
363                        String jspPath = ((I_CmsADEAction)item).getJspPath();
364                        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(jspPath)) {
365                            jspPath = OpenCms.getLinkManager().substituteLink(cms, jspPath);
366                        }
367                        CmsContextMenuEntryBean itemBean = new CmsContextMenuEntryBean(
368                            visibility.isActive(),
369                            true,
370                            jspPath,
371                            item.getTitle(locale),
372                            ((I_CmsADEAction)item).getCommandClassName(),
373                            CmsStringUtil.isEmptyOrWhitespaceOnly(visibility.getMessageKey())
374                            ? null
375                            : OpenCms.getWorkplaceManager().getMessages(locale).getString(visibility.getMessageKey()),
376                            false,
377                            null);
378                        Map<String, String> params = ((I_CmsADEAction)item).getParams();
379                        if (params != null) {
380                            params = new HashMap<String, String>(params);
381                            for (Entry<String, String> param : params.entrySet()) {
382                                String value = CmsVfsService.prepareFileNameForEditor(cms, resource, param.getValue());
383                                param.setValue(value);
384                            }
385                            itemBean.setParams(params);
386                        }
387                        entries.put(item.getId(), itemBean);
388                        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(item.getParentId())) {
389                            List<CmsContextMenuEntryBean> submenu;
390                            if (submenus.containsKey(item.getParentId())) {
391                                submenu = submenus.get(item.getParentId());
392                            } else {
393                                submenu = new ArrayList<CmsContextMenuEntryBean>();
394                                submenus.put(item.getParentId(), submenu);
395                            }
396                            submenu.add(itemBean);
397                        }
398                    }
399                }
400            }
401            List<CmsContextMenuEntryBean> result = new ArrayList<CmsContextMenuEntryBean>();
402            for (I_CmsContextMenuItem item : items) {
403                if (entries.containsKey(item.getId())) {
404                    if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(item.getParentId())) {
405                        if (entries.containsKey(item.getParentId())) {
406                            CmsContextMenuEntryBean parent = entries.get(item.getParentId());
407                            if (parent.getSubMenu() != null) {
408                                parent.getSubMenu().add(entries.get(item.getId()));
409                            }
410                        }
411                    } else {
412                        result.add(entries.get(item.getId()));
413                    }
414                }
415            }
416            return result;
417        } catch (CmsException e) {
418            // ignore, the user probably has not enough permissions to read the resource
419            LOG.debug(e.getLocalizedMessage(), e);
420        }
421        return Collections.emptyList();
422    }
423
424    /**
425     * Returns the file explorer link prefix. Append resource site path for complete link.<p>
426     *
427     * @param cms the cms context
428     * @param siteRoot the site root
429     *
430     * @return the file explorer link prefix
431     */
432    public static String getFileExplorerLink(CmsObject cms, String siteRoot) {
433
434        return CmsVaadinUtils.getWorkplaceLink()
435            + "#!"
436            + CmsFileExplorerConfiguration.APP_ID
437            + "/"
438            + cms.getRequestContext().getCurrentProject().getUuid()
439            + "!!"
440            + siteRoot
441            + "!!";
442    }
443
444    /**
445     * Returns the workplace link.<p>
446     *
447     * @param cms the cms context
448     * @param structureId the structure id of the current resource
449     *
450     * @return the workplace link
451     */
452    public static String getVaadinWorkplaceLink(CmsObject cms, CmsUUID structureId) {
453
454        String resourceRootFolder = null;
455
456        if (structureId != null) {
457            try {
458                resourceRootFolder = CmsResource.getFolderPath(
459                    cms.readResource(structureId, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED).getRootPath());
460            } catch (CmsException e) {
461                LOG.debug("Error reading resource for workplace link.", e);
462            }
463        }
464        if (resourceRootFolder == null) {
465            resourceRootFolder = cms.getRequestContext().getSiteRoot();
466        }
467        return getVaadinWorkplaceLink(cms, resourceRootFolder);
468
469    }
470
471    /**
472     * Returns the workplace link.<p>
473     *
474     * @param cms the cms context
475     * @param resourceRootFolder the resource folder root path
476     *
477     * @return the workplace link
478     */
479    public static String getVaadinWorkplaceLink(CmsObject cms, String resourceRootFolder) {
480
481        CmsSite site = OpenCms.getSiteManager().getSiteForRootPath(resourceRootFolder);
482        String siteRoot = site != null
483        ? site.getSiteRoot()
484        : OpenCms.getSiteManager().startsWithShared(resourceRootFolder)
485        ? OpenCms.getSiteManager().getSharedFolder()
486        : "";
487        String sitePath = resourceRootFolder.substring(siteRoot.length());
488        String link = getFileExplorerLink(cms, siteRoot) + sitePath;
489        return link;
490    }
491
492    /**
493     * Internal helper method for getting a validation service.<p>
494     *
495     * @param name the class name of the validation service
496     *
497     * @return the validation service
498     *
499     * @throws CmsException if something goes wrong
500     */
501    public static I_CmsValidationService getValidationService(String name) throws CmsException {
502
503        try {
504            Class<?> cls = Class.forName(name, false, I_CmsValidationService.class.getClassLoader());
505            if (!I_CmsValidationService.class.isAssignableFrom(cls)) {
506                throw new CmsIllegalArgumentException(
507                    Messages.get().container(Messages.ERR_VALIDATOR_INCORRECT_TYPE_1, name));
508            }
509            return (I_CmsValidationService)cls.newInstance();
510        } catch (ClassNotFoundException e) {
511            throw new CmsException(Messages.get().container(Messages.ERR_VALIDATOR_INSTANTIATION_FAILED_1, name), e);
512        } catch (InstantiationException e) {
513            throw new CmsException(Messages.get().container(Messages.ERR_VALIDATOR_INSTANTIATION_FAILED_1, name), e);
514        } catch (IllegalAccessException e) {
515            throw new CmsException(Messages.get().container(Messages.ERR_VALIDATOR_INSTANTIATION_FAILED_1, name), e);
516        }
517    }
518
519    /**
520     * Instantiates a class given its name using its default constructor.<p>
521     *
522     * Also checks whether the class with the given name is the subclass of another class/interface.<p>
523     *
524     *
525     * @param <T> the type of the interface/class passed as a parameter
526     *
527     * @param anInterface the interface or class against which the class should be checked
528     * @param className the name of the class
529     * @return a new instance of the class
530     *
531     * @throws CmsException if the instantiation fails
532     */
533    public static <T> T instantiate(Class<T> anInterface, String className) throws CmsException {
534
535        try {
536            Class<?> cls = Class.forName(className, false, anInterface.getClassLoader());
537            if (!anInterface.isAssignableFrom(cls)) {
538                // class was found, but does not implement the interface
539                throw new CmsIllegalArgumentException(
540                    Messages.get().container(
541                        Messages.ERR_INSTANTIATION_INCORRECT_TYPE_2,
542                        className,
543                        anInterface.getName()));
544            }
545
546            // we use another variable so we don't have to put the @SuppressWarnings on the method itself
547            @SuppressWarnings("unchecked")
548            Class<T> typedClass = (Class<T>)cls;
549            return typedClass.newInstance();
550        } catch (ClassNotFoundException e) {
551            throw new CmsException(Messages.get().container(Messages.ERR_INSTANTIATION_FAILED_1, className), e);
552        } catch (InstantiationException e) {
553            throw new CmsException(Messages.get().container(Messages.ERR_INSTANTIATION_FAILED_1, className), e);
554        } catch (IllegalAccessException e) {
555            throw new CmsException(Messages.get().container(Messages.ERR_INSTANTIATION_FAILED_1, className), e);
556        }
557    }
558
559    /**
560     * Implementation method for getting the link for a given return code.<p>
561     *
562     * @param cms the CMS context
563     * @param returnCode the return code
564     * @return the link for the return code
565     *
566     * @throws CmsException if something goes wrong
567     */
568    public static CmsReturnLinkInfo internalGetLinkForReturnCode(CmsObject cms, String returnCode) throws CmsException {
569
570        if (CmsUUID.isValidUUID(returnCode)) {
571            try {
572                CmsResource pageRes = cms.readResource(new CmsUUID(returnCode), CmsResourceFilter.IGNORE_EXPIRATION);
573                return new CmsReturnLinkInfo(
574                    OpenCms.getLinkManager().substituteLink(cms, pageRes),
575                    CmsReturnLinkInfo.Status.ok);
576            } catch (CmsVfsResourceNotFoundException e) {
577                LOG.debug(e.getLocalizedMessage(), e);
578                return new CmsReturnLinkInfo(null, CmsReturnLinkInfo.Status.notfound);
579            }
580        } else {
581            int colonIndex = returnCode.indexOf(':');
582            if (colonIndex >= 0) {
583                String before = returnCode.substring(0, colonIndex);
584                String after = returnCode.substring(colonIndex + 1);
585
586                if (CmsUUID.isValidUUID(before) && CmsUUID.isValidUUID(after)) {
587                    try {
588                        CmsUUID pageId = new CmsUUID(before);
589                        CmsUUID detailId = new CmsUUID(after);
590                        CmsResource pageRes = cms.readResource(pageId);
591                        CmsResource folder = pageRes.isFolder()
592                        ? pageRes
593                        : cms.readParentFolder(pageRes.getStructureId());
594                        String pageLink = OpenCms.getLinkManager().substituteLink(cms, folder);
595                        CmsResource detailRes = cms.readResource(detailId);
596                        String detailName = cms.getDetailName(
597                            detailRes,
598                            cms.getRequestContext().getLocale(),
599                            OpenCms.getLocaleManager().getDefaultLocales());
600                        String link = CmsFileUtil.removeTrailingSeparator(pageLink) + "/" + detailName;
601                        return new CmsReturnLinkInfo(link, CmsReturnLinkInfo.Status.ok);
602                    } catch (CmsVfsResourceNotFoundException e) {
603                        LOG.debug(e.getLocalizedMessage(), e);
604                        return new CmsReturnLinkInfo(null, CmsReturnLinkInfo.Status.notfound);
605
606                    }
607                }
608            }
609            throw new IllegalArgumentException("return code has wrong format");
610        }
611    }
612
613    /**
614     * Fetches the core data.<p>
615     *
616     * @param request the current request
617     *
618     * @return the core data
619     */
620    public static CmsCoreData prefetch(HttpServletRequest request) {
621
622        CmsCoreService srv = new CmsCoreService();
623        srv.setCms(CmsFlexController.getCmsObject(request));
624        srv.setRequest(request);
625        CmsCoreData result = null;
626        try {
627            result = srv.prefetch();
628        } finally {
629            srv.clearThreadStorage();
630        }
631        return result;
632    }
633
634    /**
635     * FInds a category in the given tree.<p>
636     *
637     * @param tree the the tree to search in
638     * @param path the path to search for
639     *
640     * @return the category with the given path or <code>null</code> if not found
641     */
642    private static CmsCategoryTreeEntry findCategory(List<CmsCategoryTreeEntry> tree, String path) {
643
644        if (path == null) {
645            return null;
646        }
647        // we assume that the category to find is descendant of tree
648        List<CmsCategoryTreeEntry> children = tree;
649        boolean found = true;
650        while (found) {
651            if (children == null) {
652                return null;
653            }
654            // since the categories are sorted it is faster to go backwards
655            found = false;
656            for (int i = children.size() - 1; i >= 0; i--) {
657                CmsCategoryTreeEntry child = children.get(i);
658                if (path.equals(child.getPath())) {
659                    return child;
660                }
661                if (path.startsWith(child.getPath())) {
662                    children = child.getChildren();
663                    found = true;
664                    break;
665                }
666            }
667        }
668        return null;
669    }
670
671    /**
672     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#changePassword(java.lang.String, java.lang.String, java.lang.String)
673     */
674    public String changePassword(String oldPassword, String newPassword, String newPasswordConfirm)
675    throws CmsRpcException {
676
677        CmsObject cms = getCmsObject();
678        CmsPasswordInfo passwordBean = new CmsPasswordInfo(cms);
679        Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms);
680        try {
681            passwordBean.setCurrentPwd(oldPassword);
682            passwordBean.setNewPwd(newPassword);
683            passwordBean.setConfirmation(newPasswordConfirm);
684            passwordBean.applyChanges();
685            return null;
686        } catch (CmsSecurityException e) {
687            LOG.error(e.getLocalizedMessage(), e);
688            return e.getMessageContainer().key(wpLocale);
689        } catch (CmsIllegalArgumentException e) {
690            LOG.warn(e.getLocalizedMessage(), e);
691            return e.getMessageContainer().key(wpLocale);
692        } catch (Exception e) {
693            error(e);
694            return null; // will never be executed
695        }
696    }
697
698    /**
699     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#createUUID()
700     */
701    public CmsUUID createUUID() {
702
703        return new CmsUUID();
704    }
705
706    /**
707     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getBroadcast()
708     */
709    public List<CmsBroadcastMessage> getBroadcast() {
710
711        Set<CmsBroadcast> repeatedBroadcasts = new HashSet<CmsBroadcast>();
712        OpenCms.getWorkplaceManager().checkWorkplaceRequest(getRequest(), getCmsObject());
713        CmsSessionInfo sessionInfo = OpenCms.getSessionManager().getSessionInfo(getRequest().getSession());
714        if (sessionInfo == null) {
715            return null;
716        }
717        String sessionId = sessionInfo.getSessionId().toString();
718        Buffer messageQueue = OpenCms.getSessionManager().getBroadcastQueue(sessionId);
719        if (!messageQueue.isEmpty()) {
720            CmsMessages messages = org.opencms.workplace.Messages.get().getBundle(
721                OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject()));
722            List<CmsBroadcastMessage> result = new ArrayList<CmsBroadcastMessage>();
723            // the user has pending messages, display them all
724            while (!messageQueue.isEmpty()) {
725
726                CmsBroadcast broadcastMessage = (CmsBroadcast)messageQueue.remove();
727                if ((broadcastMessage.getLastDisplay()
728                    + CmsBroadcast.DISPLAY_AGAIN_TIME) < System.currentTimeMillis()) {
729                    CmsUserIconHelper helper = OpenCms.getWorkplaceAppManager().getUserIconHelper();
730                    String picPath = "";
731                    if (broadcastMessage.getUser() != null) {
732                        picPath = helper.getSmallIconPath(getCmsObject(), broadcastMessage.getUser());
733                    }
734                    CmsBroadcastMessage message = new CmsBroadcastMessage(
735                        broadcastMessage.getUser() != null
736                        ? broadcastMessage.getUser().getName()
737                        : messages.key(org.opencms.workplace.Messages.GUI_LABEL_BROADCAST_FROM_SYSTEM_0),
738                        picPath,
739                        messages.getDateTime(broadcastMessage.getSendTime()),
740                        broadcastMessage.getMessage());
741                    result.add(message);
742                    if (broadcastMessage.isRepeat()) {
743                        repeatedBroadcasts.add(
744                            new CmsBroadcast(
745                                broadcastMessage.getUser(),
746                                broadcastMessage.getMessage(),
747                                broadcastMessage.getSendTime(),
748                                System.currentTimeMillis(),
749                                true));
750                    }
751                } else {
752                    repeatedBroadcasts.add(broadcastMessage);
753                }
754            }
755            if (!repeatedBroadcasts.isEmpty()) {
756                for (CmsBroadcast broadcast : repeatedBroadcasts) {
757                    messageQueue.add(broadcast);
758                }
759            }
760            return result;
761        }
762        // no message pending, return null
763        return null;
764    }
765
766    /**
767     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getCategories(java.lang.String, boolean, java.lang.String)
768     */
769    public List<CmsCategoryTreeEntry> getCategories(String fromPath, boolean includeSubCats, String refPath)
770    throws CmsRpcException {
771
772        return getCategories(fromPath, includeSubCats, refPath, false);
773    }
774
775    /**
776     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getCategories(java.lang.String, boolean, java.lang.String, boolean)
777     */
778    public List<CmsCategoryTreeEntry> getCategories(
779        String fromPath,
780        boolean includeSubCats,
781        String refPath,
782        boolean showWithRepositories)
783    throws CmsRpcException {
784
785        CmsObject cms = getCmsObject();
786        CmsCategoryService catService = CmsCategoryService.getInstance();
787
788        List<String> repositories = new ArrayList<String>();
789        repositories.addAll(catService.getCategoryRepositories(getCmsObject(), refPath));
790
791        List<CmsCategoryTreeEntry> result = null;
792        try {
793            // get the categories
794            List<CmsCategory> categories = catService.readCategoriesForRepositories(
795                cms,
796                fromPath,
797                includeSubCats,
798                repositories,
799                showWithRepositories);
800            categories = catService.localizeCategories(
801                cms,
802                categories,
803                OpenCms.getWorkplaceManager().getWorkplaceLocale(cms));
804            result = buildCategoryTree(cms, categories);
805        } catch (Throwable e) {
806            error(e);
807        }
808        return result;
809    }
810
811    /**
812     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getCategoriesForSitePath(java.lang.String)
813     */
814    public List<CmsCategoryTreeEntry> getCategoriesForSitePath(String sitePath) throws CmsRpcException {
815
816        List<CmsCategoryTreeEntry> result = null;
817        CmsObject cms = getCmsObject();
818        try {
819            result = getCategoriesForSitePathStatic(cms, sitePath);
820        } catch (Throwable e) {
821            error(e);
822        }
823        return result;
824    }
825
826    /**
827     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getCategoryInfo(org.opencms.util.CmsUUID)
828     */
829    public CmsResourceCategoryInfo getCategoryInfo(CmsUUID structureId) throws CmsRpcException {
830
831        CmsObject cms = getCmsObject();
832        CmsCategoryService catService = CmsCategoryService.getInstance();
833        try {
834            CmsResource resource = cms.readResource(structureId, CmsResourceFilter.ignoreExpirationOffline(cms));
835            List<CmsCategory> categories = catService.readResourceCategories(cms, resource);
836            List<String> currentCategories = new ArrayList<String>();
837            for (CmsCategory category : categories) {
838                currentCategories.add(category.getPath());
839            }
840            return new CmsResourceCategoryInfo(
841                structureId,
842                CmsVfsService.getPageInfoWithLock(cms, resource),
843                currentCategories,
844                getCategories(
845                    null,
846                    true,
847                    cms.getSitePath(resource),
848                    OpenCms.getWorkplaceManager().isDisplayCategoriesByRepository()));
849        } catch (CmsException e) {
850            error(e);
851        }
852        return null;
853    }
854
855    /**
856     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getContextMenuEntries(org.opencms.util.CmsUUID, org.opencms.gwt.shared.CmsCoreData.AdeContext)
857     */
858    public List<CmsContextMenuEntryBean> getContextMenuEntries(CmsUUID structureId, AdeContext context)
859    throws CmsRpcException {
860
861        List<CmsContextMenuEntryBean> result = null;
862        try {
863            result = getContextMenuEntries(getCmsObject(), structureId, context);
864        } catch (Throwable e) {
865            error(e);
866        }
867        return result;
868    }
869
870    /**
871     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getLinkForReturnCode(java.lang.String)
872     */
873    public CmsReturnLinkInfo getLinkForReturnCode(String returnCode) throws CmsRpcException {
874
875        try {
876            return internalGetLinkForReturnCode(getCmsObject(), returnCode);
877        } catch (Throwable e) {
878            error(e);
879            return null;
880
881        }
882    }
883
884    /**
885     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getResourceState(org.opencms.util.CmsUUID)
886     */
887    public CmsResourceState getResourceState(CmsUUID structureId) throws CmsRpcException {
888
889        CmsObject cms = getCmsObject();
890        CmsResourceState result = null;
891        try {
892            try {
893                CmsResource res = cms.readResource(structureId, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED);
894                result = res.getState();
895            } catch (CmsVfsResourceNotFoundException e) {
896                LOG.debug(e.getLocalizedMessage(), e);
897                result = CmsResourceState.STATE_DELETED;
898            }
899        } catch (CmsException e) {
900            error(e);
901        }
902        return result;
903    }
904
905    /**
906     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getUniqueFileName(java.lang.String, java.lang.String)
907     */
908    public String getUniqueFileName(String parentFolder, String baseName) {
909
910        return OpenCms.getResourceManager().getNameGenerator().getUniqueFileName(
911            getCmsObject(),
912            parentFolder,
913            baseName);
914    }
915
916    /**
917     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getUserInfo()
918     */
919    public UserInfo getUserInfo() {
920
921        CmsObject cms = getCmsObject();
922        CmsRoleManager roleManager = OpenCms.getRoleManager();
923        boolean isAdmin = roleManager.hasRole(cms, CmsRole.ADMINISTRATOR);
924        boolean isDeveloper = roleManager.hasRole(cms, CmsRole.DEVELOPER);
925        boolean isCategoryManager = roleManager.hasRole(cms, CmsRole.CATEGORY_EDITOR);
926        boolean isWorkplaceUser = roleManager.hasRole(cms, CmsRole.WORKPLACE_USER);
927        UserInfo userInfo = new UserInfo(
928            cms.getRequestContext().getCurrentUser().getName(),
929            OpenCms.getWorkplaceAppManager().getUserIconHelper().getSmallIconPath(
930                cms,
931                cms.getRequestContext().getCurrentUser()),
932            isAdmin,
933            isDeveloper,
934            isCategoryManager,
935            isWorkplaceUser,
936            cms.getRequestContext().getCurrentUser().isManaged());
937        return userInfo;
938    }
939
940    /**
941     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getWorkplaceLink(org.opencms.util.CmsUUID)
942     */
943    public String getWorkplaceLink(CmsUUID structureId) throws CmsRpcException {
944
945        String result = null;
946        CmsObject cms = getCmsObject();
947        try {
948            String resourceRootFolder = structureId != null
949            ? CmsResource.getFolderPath(
950                cms.readResource(structureId, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED).getRootPath())
951            : cms.getRequestContext().getSiteRoot();
952            result = getVaadinWorkplaceLink(cms, resourceRootFolder);
953        } catch (Throwable e) {
954            error(e);
955        }
956        return result;
957    }
958
959    /**
960     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#loadUserSettings()
961     */
962    public CmsUserSettingsBean loadUserSettings() throws CmsRpcException {
963
964        CmsObject cms = getCmsObject();
965        CmsClientUserSettingConverter converter = new CmsClientUserSettingConverter(cms, getRequest(), getResponse());
966        try {
967            return converter.loadSettings();
968        } catch (Exception e) {
969            error(e);
970            return null;
971        }
972    }
973
974    /**
975     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#lockIfExists(java.lang.String)
976     */
977    public String lockIfExists(String sitePath) throws CmsRpcException {
978
979        CmsObject cms = getCmsObject();
980        String errorMessage = null;
981        try {
982            if (cms.existsResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION)) {
983
984                try {
985                    ensureLock(cms.readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION));
986                } catch (CmsException e) {
987                    errorMessage = e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms));
988                }
989
990            } else {
991                // check if parent folder may be locked by the current user
992                String parentFolder = CmsResource.getParentFolder(sitePath);
993                while ((parentFolder != null)
994                    && !cms.existsResource(parentFolder, CmsResourceFilter.IGNORE_EXPIRATION)) {
995                    parentFolder = CmsResource.getParentFolder(parentFolder);
996                }
997                if (parentFolder != null) {
998                    CmsResource ancestorFolder = cms.readResource(parentFolder, CmsResourceFilter.IGNORE_EXPIRATION);
999                    CmsUser user = cms.getRequestContext().getCurrentUser();
1000                    CmsLock lock = cms.getLock(ancestorFolder);
1001                    if (!lock.isLockableBy(user)) {
1002                        errorMessage = "Can not lock parent folder '" + parentFolder + "'.";
1003                    }
1004                } else {
1005                    errorMessage = "Can not access any parent folder.";
1006                }
1007            }
1008        } catch (Throwable e) {
1009            error(e);
1010        }
1011
1012        return errorMessage;
1013    }
1014
1015    /**
1016     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#lockIfExists(java.lang.String, long)
1017     */
1018    public String lockIfExists(String sitePath, long loadTime) throws CmsRpcException {
1019
1020        CmsObject cms = getCmsObject();
1021        String errorMessage = null;
1022        try {
1023            if (cms.existsResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION)) {
1024
1025                try {
1026                    CmsResource resource = cms.readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION);
1027                    if (resource.getDateLastModified() > loadTime) {
1028                        // the resource has been changed since it was loaded
1029                        CmsUser user = null;
1030                        try {
1031                            user = cms.readUser(resource.getUserLastModified());
1032                        } catch (CmsException e) {
1033                            // ignore
1034                        }
1035                        CmsMessages messages = Messages.get().getBundle(
1036                            OpenCms.getWorkplaceManager().getWorkplaceLocale(cms));
1037                        return user != null
1038                        ? messages.key(
1039                            Messages.ERR_LOCKING_MODIFIED_RESOURCE_2,
1040                            resource.getRootPath(),
1041                            user.getFullName())
1042                        : messages.key(Messages.ERR_LOCKING_MODIFIED_RESOURCE_1, resource.getRootPath());
1043                    }
1044                    ensureLock(resource);
1045                } catch (CmsException e) {
1046                    errorMessage = e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms));
1047                }
1048
1049            } else {
1050                // check if parent folder may be locked by the current user
1051                String parentFolder = CmsResource.getParentFolder(sitePath);
1052                while ((parentFolder != null)
1053                    && !cms.existsResource(parentFolder, CmsResourceFilter.IGNORE_EXPIRATION)) {
1054                    parentFolder = CmsResource.getParentFolder(parentFolder);
1055                }
1056                if (parentFolder != null) {
1057                    CmsResource ancestorFolder = cms.readResource(parentFolder, CmsResourceFilter.IGNORE_EXPIRATION);
1058                    CmsUser user = cms.getRequestContext().getCurrentUser();
1059                    CmsLock lock = cms.getLock(ancestorFolder);
1060                    if (!lock.isLockableBy(user)) {
1061                        errorMessage = "Can not lock parent folder '" + parentFolder + "'.";
1062                    }
1063                } else {
1064                    errorMessage = "Can not access any parent folder.";
1065                }
1066            }
1067        } catch (Throwable e) {
1068            error(e);
1069        }
1070
1071        return errorMessage;
1072    }
1073
1074    /**
1075     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#lockTemp(org.opencms.util.CmsUUID)
1076     */
1077    public String lockTemp(CmsUUID structureId) throws CmsRpcException {
1078
1079        CmsObject cms = getCmsObject();
1080        try {
1081            try {
1082                ensureLock(structureId);
1083            } catch (CmsException e) {
1084                return e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms));
1085            }
1086        } catch (Throwable e) {
1087            error(e);
1088        }
1089        return null;
1090    }
1091
1092    /**
1093     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#lockTemp(org.opencms.util.CmsUUID, long)
1094     */
1095    public String lockTemp(CmsUUID structureId, long loadTime) throws CmsRpcException {
1096
1097        CmsObject cms = getCmsObject();
1098        try {
1099            try {
1100                CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
1101                if (resource.getDateLastModified() > loadTime) {
1102                    // the resource has been changed since it was loaded
1103                    CmsUser user = null;
1104                    try {
1105                        user = cms.readUser(resource.getUserLastModified());
1106                    } catch (CmsException e) {
1107                        // ignore
1108                    }
1109                    CmsMessages messages = Messages.get().getBundle(
1110                        OpenCms.getWorkplaceManager().getWorkplaceLocale(cms));
1111                    return user != null
1112                    ? messages.key(Messages.ERR_LOCKING_MODIFIED_RESOURCE_2, resource.getRootPath(), user.getFullName())
1113                    : messages.key(Messages.ERR_LOCKING_MODIFIED_RESOURCE_1, resource.getRootPath());
1114                }
1115                ensureLock(resource);
1116            } catch (CmsException e) {
1117                return e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms));
1118            }
1119        } catch (Throwable e) {
1120            error(e);
1121        }
1122        return null;
1123    }
1124
1125    /**
1126     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#prefetch()
1127     */
1128    public CmsCoreData prefetch() {
1129
1130        CmsObject cms = getCmsObject();
1131        String navigationUri = cms.getRequestContext().getUri();
1132        boolean toolbarVisible = CmsADESessionCache.getCache(getRequest(), getCmsObject()).isToolbarVisible();
1133        boolean isShowHelp = OpenCms.getADEManager().isShowEditorHelp(cms);
1134
1135        CmsUUID structureId = null;
1136
1137        try {
1138            CmsResource requestedResource = cms.readResource(cms.getRequestContext().getUri());
1139            structureId = requestedResource.getStructureId();
1140        } catch (CmsException e) {
1141            // may happen in case of VAADIN UI
1142            LOG.debug("Could not read resource for URI.", e);
1143            structureId = CmsUUID.getNullUUID();
1144        }
1145        String loginUrl = CmsWorkplaceLoginHandler.LOGIN_FORM;
1146        try {
1147            loginUrl = cms.readPropertyObject(
1148                cms.getRequestContext().getUri(),
1149                CmsPropertyDefinition.PROPERTY_LOGIN_FORM,
1150                true).getValue(loginUrl);
1151        } catch (CmsException e) {
1152            log(e.getLocalizedMessage(), e);
1153        }
1154        String defaultWorkplaceLink = OpenCms.getSystemInfo().getWorkplaceContext();
1155        Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms);
1156        UserInfo userInfo = getUserInfo();
1157        String aboutLink = OpenCms.getLinkManager().substituteLink(
1158            getCmsObject(),
1159            "/system/workplace/commons/about.jsp");
1160        String tinyMCE = CmsWorkplace.getStaticResourceUri("/editors/tinymce/jscripts/tinymce/tinymce.min.js");
1161        CmsCoreData data = new CmsCoreData(
1162            EDITOR_URI,
1163            EDITOR_BACKLINK_URI,
1164            loginUrl,
1165            OpenCms.getStaticExportManager().getVfsPrefix(),
1166            getFileExplorerLink(cms, cms.getRequestContext().getSiteRoot()),
1167            OpenCms.getSystemInfo().getStaticResourceContext(),
1168            CmsEmbeddedDialogsUI.getEmbeddedDialogsContextPath(),
1169            cms.getRequestContext().getSiteRoot(),
1170            cms.getRequestContext().getCurrentProject().getId(),
1171            cms.getRequestContext().getLocale().toString(),
1172            wpLocale.toString(),
1173            cms.getRequestContext().getUri(),
1174            navigationUri,
1175            structureId,
1176            new HashMap<String, String>(OpenCms.getResourceManager().getExtensionMapping()),
1177            CmsIconUtil.getExtensionIconMapping(),
1178            System.currentTimeMillis(),
1179            isShowHelp,
1180            toolbarVisible,
1181            defaultWorkplaceLink,
1182            aboutLink,
1183            userInfo,
1184            OpenCms.getWorkplaceManager().getFileBytesMaxUploadSize(getCmsObject()),
1185            OpenCms.getWorkplaceManager().isKeepAlive(),
1186            OpenCms.getADEManager().getParameters(getCmsObject()));
1187        CmsTinyMCEData tinyMCEData = new CmsTinyMCEData();
1188        tinyMCEData.setLink(tinyMCE);
1189        data.setTinymce(tinyMCEData);
1190        return data;
1191    }
1192
1193    /**
1194     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#saveUserSettings(java.util.Map, java.util.Set)
1195     */
1196    public void saveUserSettings(Map<String, String> userSettings, Set<String> edited) throws CmsRpcException {
1197
1198        try {
1199            CmsObject cms = getCmsObject();
1200            CmsClientUserSettingConverter converter = new CmsClientUserSettingConverter(
1201                cms,
1202                getRequest(),
1203                getResponse());
1204            userSettings.keySet().retainAll(edited);
1205            converter.saveSettings(userSettings);
1206        } catch (Exception e) {
1207            error(e);
1208        }
1209    }
1210
1211    /**
1212     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#setResourceCategories(org.opencms.util.CmsUUID, java.util.List)
1213     */
1214    public void setResourceCategories(CmsUUID structureId, List<String> categories) throws CmsRpcException {
1215
1216        CmsObject cms = getCmsObject();
1217        CmsCategoryService catService = CmsCategoryService.getInstance();
1218        try {
1219            CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
1220            ensureLock(resource);
1221            String sitePath = cms.getSitePath(resource);
1222            List<CmsCategory> previousCategories = catService.readResourceCategories(cms, resource);
1223            for (CmsCategory category : previousCategories) {
1224                if (categories.contains(category.getPath())) {
1225                    categories.remove(category.getPath());
1226                } else {
1227                    catService.removeResourceFromCategory(cms, sitePath, category);
1228                }
1229            }
1230            for (String path : categories) {
1231                catService.addResourceToCategory(cms, sitePath, path);
1232            }
1233            tryUnlock(resource);
1234        } catch (Throwable t) {
1235            error(t);
1236        }
1237    }
1238
1239    /**
1240     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#setShowEditorHelp(boolean)
1241     */
1242    public void setShowEditorHelp(boolean visible) throws CmsRpcException {
1243
1244        try {
1245            OpenCms.getADEManager().setShowEditorHelp(getCmsObject(), visible);
1246        } catch (Throwable e) {
1247            error(e);
1248        }
1249    }
1250
1251    /**
1252     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#setToolbarVisible(boolean)
1253     */
1254    public void setToolbarVisible(boolean visible) throws CmsRpcException {
1255
1256        try {
1257            ensureSession();
1258            CmsADESessionCache.getCache(getRequest(), getCmsObject()).setToolbarVisible(visible);
1259        } catch (Throwable e) {
1260            error(e);
1261        }
1262    }
1263
1264    /**
1265     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#unlock(org.opencms.util.CmsUUID)
1266     */
1267    public String unlock(CmsUUID structureId) throws CmsRpcException {
1268
1269        CmsObject cms = getCmsObject();
1270        try {
1271            CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
1272            tryUnlock(resource);
1273        } catch (CmsException e) {
1274            return e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms));
1275        } catch (Throwable e) {
1276            error(e);
1277        }
1278        return null;
1279    }
1280
1281    /**
1282     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#unlock(java.lang.String)
1283     */
1284    public String unlock(String sitePath) throws CmsRpcException {
1285
1286        try {
1287            CmsObject cms = OpenCms.initCmsObject(getCmsObject());
1288            cms.getRequestContext().setSiteRoot("");
1289            if (cms.existsResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION)) {
1290                CmsResource resource = cms.readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION);
1291                tryUnlock(resource);
1292            }
1293        } catch (CmsException e) {
1294            return e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject()));
1295        } catch (Throwable e) {
1296            error(e);
1297        }
1298        return null;
1299    }
1300
1301    /**
1302     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#validate(java.util.Map)
1303     */
1304    public Map<String, CmsValidationResult> validate(Map<String, CmsValidationQuery> validationQueries)
1305    throws CmsRpcException {
1306
1307        try {
1308            Map<String, CmsValidationResult> result = new HashMap<String, CmsValidationResult>();
1309            for (Map.Entry<String, CmsValidationQuery> queryEntry : validationQueries.entrySet()) {
1310                String fieldName = queryEntry.getKey();
1311                CmsValidationQuery query = queryEntry.getValue();
1312                result.put(fieldName, validate(query.getValidatorId(), query.getValue(), query.getConfig()));
1313            }
1314            return result;
1315        } catch (Throwable e) {
1316            error(e);
1317        }
1318        return null;
1319    }
1320
1321    /**
1322     * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#validate(java.lang.String, java.util.Map, java.util.Map, java.lang.String)
1323     */
1324    public Map<String, CmsValidationResult> validate(
1325        String formValidatorClass,
1326        Map<String, CmsValidationQuery> validationQueries,
1327        Map<String, String> values,
1328        String config)
1329    throws CmsRpcException {
1330
1331        try {
1332            I_CmsFormValidator formValidator = instantiate(I_CmsFormValidator.class, formValidatorClass);
1333            return formValidator.validate(getCmsObject(), validationQueries, values, config);
1334        } catch (Throwable e) {
1335            error(e);
1336        }
1337        return null;
1338    }
1339
1340    /**
1341     * Collect GWT build ids from the different ADE modules.<p>
1342     *
1343     * @return the map of GWT build ids
1344     */
1345    protected Map<String, String> getBuildIds() {
1346
1347        List<CmsModule> modules = OpenCms.getModuleManager().getAllInstalledModules();
1348        Map<String, String> result = new HashMap<String, String>();
1349        for (CmsModule module : modules) {
1350            String buildid = module.getParameter(CmsCoreData.KEY_GWT_BUILDID);
1351            if (buildid != null) {
1352                result.put(module.getName(), buildid);
1353            }
1354        }
1355        return result;
1356    }
1357
1358    /**
1359     * Helper method for locking a resource which returns some information on whether the locking
1360     * failed, and why.<p>
1361     *
1362     * @param structureId the structure id of the resource
1363     * @return the locking information
1364     *
1365     * @throws CmsException if something went wrong
1366     */
1367    protected CmsLockInfo getLock(CmsUUID structureId) throws CmsException {
1368
1369        CmsResource res = getCmsObject().readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
1370        return getLock(getCmsObject().getSitePath(res));
1371    }
1372
1373    /**
1374     * Helper method for locking a resource which returns some information on whether the locking
1375     * failed, and why.<p>
1376     *
1377     * @param sitepath the site path of the resource to lock
1378     * @return the locking information
1379     *
1380     * @throws CmsException if something went wrong
1381     */
1382    protected CmsLockInfo getLock(String sitepath) throws CmsException {
1383
1384        CmsObject cms = getCmsObject();
1385        CmsUser user = cms.getRequestContext().getCurrentUser();
1386        CmsLock lock = cms.getLock(sitepath);
1387        if (lock.isOwnedBy(user)) {
1388            return CmsLockInfo.forSuccess();
1389        }
1390        if (lock.getUserId().isNullUUID()) {
1391            cms.lockResourceTemporary(sitepath);
1392            return CmsLockInfo.forSuccess();
1393        }
1394        CmsUser owner = cms.readUser(lock.getUserId());
1395        return CmsLockInfo.forLockedResource(owner.getName());
1396    }
1397
1398    /**
1399     * Internal helper method for validating a single value.<p>
1400     *
1401     * @param validator the class name of the validation service
1402     * @param value the value to validate
1403     * @param config the configuration for the validation service
1404     *
1405     * @return the result of the validation
1406     *
1407     * @throws Exception if something goes wrong
1408     */
1409    private CmsValidationResult validate(String validator, String value, String config) throws Exception {
1410
1411        I_CmsValidationService validationService = getValidationService(validator);
1412        return validationService.validate(getCmsObject(), value, config);
1413    }
1414}