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 GmbH & Co. KG, 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.file;
029
030import org.opencms.db.CmsDbEntryNotFoundException;
031import org.opencms.db.CmsPublishedResource;
032import org.opencms.db.CmsResourceState;
033import org.opencms.db.CmsSecurityManager;
034import org.opencms.db.log.CmsLogEntry;
035import org.opencms.db.log.CmsLogFilter;
036import org.opencms.db.urlname.CmsUrlNameMappingEntry;
037import org.opencms.db.urlname.CmsUrlNameMappingFilter;
038import org.opencms.file.CmsResource.CmsResourceDeleteMode;
039import org.opencms.file.history.CmsHistoryPrincipal;
040import org.opencms.file.history.CmsHistoryProject;
041import org.opencms.file.history.I_CmsHistoryResource;
042import org.opencms.file.types.I_CmsResourceType;
043import org.opencms.i18n.CmsLocaleGroupService;
044import org.opencms.lock.CmsLock;
045import org.opencms.lock.CmsLockFilter;
046import org.opencms.lock.CmsLockType;
047import org.opencms.main.CmsException;
048import org.opencms.main.CmsIllegalArgumentException;
049import org.opencms.main.I_CmsEventListener;
050import org.opencms.main.OpenCms;
051import org.opencms.relations.CmsRelation;
052import org.opencms.relations.CmsRelationFilter;
053import org.opencms.relations.CmsRelationType;
054import org.opencms.report.I_CmsReport;
055import org.opencms.security.CmsAccessControlEntry;
056import org.opencms.security.CmsAccessControlList;
057import org.opencms.security.CmsOrganizationalUnit;
058import org.opencms.security.CmsPermissionSet;
059import org.opencms.security.CmsPrincipal;
060import org.opencms.security.CmsRole;
061import org.opencms.security.CmsRoleViolationException;
062import org.opencms.security.CmsSecurityException;
063import org.opencms.security.I_CmsPermissionHandler;
064import org.opencms.security.I_CmsPrincipal;
065import org.opencms.util.CmsPair;
066import org.opencms.util.CmsStringUtil;
067import org.opencms.util.CmsUUID;
068import org.opencms.xml.content.CmsNumberSuffixNameSequence;
069
070import java.util.ArrayList;
071import java.util.Collections;
072import java.util.Iterator;
073import java.util.List;
074import java.util.Locale;
075import java.util.Map;
076import java.util.Set;
077
078/**
079 * This pivotal class provides all authorized access to the OpenCms VFS resources.<p>
080 *
081 * It encapsulates user identification and permissions.
082 * Think of it as an initialized "shell" to access the OpenCms VFS.
083 * Every call to a method here will be checked for user permissions
084 * according to the <code>{@link org.opencms.file.CmsRequestContext}</code> this CmsObject instance was created with.<p>
085 *
086 * From a JSP page running in OpenCms, use <code>{@link org.opencms.jsp.CmsJspBean#getCmsObject()}</code> to gain
087 * access to the current users CmsObject. Usually this is done with a <code>{@link org.opencms.jsp.CmsJspActionElement}</code>.<p>
088 *
089 * To generate a new instance of this class in your application, use
090 * <code>{@link org.opencms.main.OpenCms#initCmsObject(String)}</code>. The argument String should be
091 * the name of the guest user, usually "Guest" and more formally obtained by <code>{@link org.opencms.db.CmsDefaultUsers#getUserGuest()}</code>.
092 * This will give you an initialized context with guest user permissions.
093 * Then use <code>{@link CmsObject#loginUser(String, String)}</code> to log in the user you want.
094 * Obviously you need the password for the new user.
095 * You should never try to create an instance of this class using the constructor,
096 * this is reserved for internal operation only.<p>
097 *
098 * @since 6.0.0
099 */
100public final class CmsObject {
101
102    /** The request context. */
103    protected CmsRequestContext m_context;
104
105    /** The security manager to access the cms. */
106    protected CmsSecurityManager m_securityManager;
107
108    /**
109     * Connects an OpenCms user context to a running database.<p>
110     *
111     * <b>Please note:</b> This constructor is internal to OpenCms and not for public use.
112     * If you want to create a new instance of a <code>{@link CmsObject}</code> in your application,
113     * use <code>{@link org.opencms.main.OpenCms#initCmsObject(String)}</code>.<p>
114     *
115     * @param securityManager the security manager
116     * @param context the request context that contains the user authentication
117     */
118    public CmsObject(CmsSecurityManager securityManager, CmsRequestContext context) {
119
120        init(securityManager, context);
121    }
122
123    /**
124     * Adds a new relation to the given resource.<p>
125     *
126     * @param resource the source resource
127     * @param target the target resource
128     * @param type the type of the relation
129     *
130     * @throws CmsException if something goes wrong
131     */
132    public void addRelationToResource(CmsResource resource, CmsResource target, String type) throws CmsException {
133
134        createRelation(resource, target, type, false);
135    }
136
137    /**
138     * Adds a new relation to the given resource.<p>
139     *
140     * @param resourceName the name of the source resource
141     * @param targetPath the path of the target resource
142     * @param type the type of the relation
143     *
144     * @throws CmsException if something goes wrong
145     */
146    public void addRelationToResource(String resourceName, String targetPath, String type) throws CmsException {
147
148        createRelation(resourceName, targetPath, type, false);
149    }
150
151    /**
152     * Convenience method to add the site root from the current user's
153     * request context to the given resource name.<p>
154     *
155     * @param resourcename the resource name
156     *
157     * @return the resource name with the site root added
158     *
159     * @see CmsRequestContext#addSiteRoot(String)
160     */
161    public String addSiteRoot(String resourcename) {
162
163        return m_context.addSiteRoot(resourcename);
164    }
165
166    /**
167     * Adds a user to a group.<p>
168     *
169     * @param username the name of the user that is to be added to the group
170     * @param groupname the name of the group
171     *
172     * @throws CmsException if something goes wrong
173     */
174    public void addUserToGroup(String username, String groupname) throws CmsException {
175
176        m_securityManager.addUserToGroup(m_context, username, groupname, false);
177    }
178
179    /**
180     * This method works just like {@link CmsObject#adjustLinks(String, String)}, but you can specify multiple source
181     * files, and the target folder is interpreted as the folder into which the source files have been copied.<p>
182     *
183     * @param sourceFiles the list of source files
184     * @param targetParentFolder the folder into which the source files have been copied
185     *
186     * @throws CmsException if something goes wrong
187     */
188    public void adjustLinks(List<String> sourceFiles, String targetParentFolder) throws CmsException {
189
190        CmsObject cms = OpenCms.initCmsObject(this);
191        cms.getRequestContext().setSiteRoot("");
192        List<String> rootSourceFiles = new ArrayList<String>();
193        for (String sourceFile : sourceFiles) {
194            rootSourceFiles.add(addSiteRoot(sourceFile));
195        }
196        String rootTargetParentFolder = addSiteRoot(targetParentFolder);
197
198        CmsLinkRewriter rewriter = new CmsLinkRewriter(cms, rootSourceFiles, rootTargetParentFolder);
199        rewriter.rewriteLinks();
200    }
201
202    /**
203     * This method works just like {@link CmsObject#adjustLinks(String, String)}, but instead of specifying
204     * a single source and target folder, you can specify multiple sources and the corresponding targets in
205     * a map of strings.
206     *
207     * @param sourceTargetMap a map with the source files as keys and the corresponding targets as values
208     * @param targetParentFolder the folder into which the source files have been copied
209     *
210     * @throws CmsException if something goes wrong
211     */
212    public void adjustLinks(Map<String, String> sourceTargetMap, String targetParentFolder) throws CmsException {
213
214        CmsObject cms = OpenCms.initCmsObject(this);
215        cms.getRequestContext().setSiteRoot("");
216        List<CmsPair<String, String>> sourcesAndTargets = new ArrayList<CmsPair<String, String>>();
217        for (Map.Entry<String, String> entry : sourceTargetMap.entrySet()) {
218            String rootSource = addSiteRoot(entry.getKey());
219            String rootTarget = addSiteRoot(entry.getValue());
220            sourcesAndTargets.add(CmsPair.create(rootSource, rootTarget));
221        }
222        String rootTargetParentFolder = addSiteRoot(targetParentFolder);
223        CmsLinkRewriter rewriter = new CmsLinkRewriter(cms, rootTargetParentFolder, sourcesAndTargets);
224        rewriter.rewriteLinks();
225    }
226
227    /**
228     * Adjusts all links in the target folder that point to the source folder
229     * so that they are kept "relative" in the target folder where possible.
230     *
231     * If a link is found from the target folder to the source folder,
232     * then the target folder is checked if a target of the same name
233     * is found also "relative" inside the target Folder, and if so,
234     * the link is changed to that "relative" target. This is mainly used to keep
235     * relative links inside a copied folder structure intact.
236     *
237     * Example: Image we have folder /folderA/ that contains files
238     * /folderA/x1 and /folderA/y1. x1 has a link to y1 and y1 to x1.
239     * Now someone copies /folderA/ to /folderB/. So we end up with
240     * /folderB/x2 and /folderB/y2. Because of the link mechanism in OpenCms,
241     * x2 will have a link to y1 and y2 to x1. By using this method,
242     * the links from x2 to y1 will be replaced by a link x2 to y2,
243     * and y2 to x1 with y2 to x2.
244     *
245     * Link replacement works for links in XML files as well as relation only
246     * type links.
247     *
248     * @param sourceFolder the source folder
249     * @param targetFolder the target folder
250     *
251     * @throws CmsException if something goes wrong
252     */
253    public void adjustLinks(String sourceFolder, String targetFolder) throws CmsException {
254
255        String rootSourceFolder = addSiteRoot(sourceFolder);
256        String rootTargetFolder = addSiteRoot(targetFolder);
257        String siteRoot = getRequestContext().getSiteRoot();
258        getRequestContext().setSiteRoot("");
259        try {
260            CmsLinkRewriter linkRewriter = new CmsLinkRewriter(this, rootSourceFolder, rootTargetFolder);
261            linkRewriter.rewriteLinks();
262        } finally {
263            getRequestContext().setSiteRoot(siteRoot);
264        }
265    }
266
267    /**
268     * Changes the access control for a given resource and a given principal(user/group).<p>
269     *
270     * @param resourceName name of the resource
271     * @param principalType the type of the principal (currently group or user):
272     *      <ul>
273     *          <li><code>{@link I_CmsPrincipal#PRINCIPAL_USER}</code></li>
274     *          <li><code>{@link I_CmsPrincipal#PRINCIPAL_GROUP}</code></li>
275     *      </ul>
276     * @param principalName name of the principal
277     * @param allowedPermissions bit set of allowed permissions
278     * @param deniedPermissions bit set of denied permissions
279     * @param flags additional flags of the access control entry
280     *
281     * @throws CmsException if something goes wrong
282     */
283    public void chacc(
284        String resourceName,
285        String principalType,
286        String principalName,
287        int allowedPermissions,
288        int deniedPermissions,
289        int flags)
290    throws CmsException {
291
292        CmsResource res = readResource(resourceName, CmsResourceFilter.ALL);
293
294        CmsAccessControlEntry acEntry = null;
295        try {
296            I_CmsPrincipal principal = CmsPrincipal.readPrincipal(this, principalType, principalName);
297            acEntry = new CmsAccessControlEntry(
298                res.getResourceId(),
299                principal.getId(),
300                allowedPermissions,
301                deniedPermissions,
302                flags);
303            acEntry.setFlagsForPrincipal(principal);
304        } catch (CmsDbEntryNotFoundException e) {
305            // check for special ids
306            if (principalName.equalsIgnoreCase(CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_NAME)) {
307                acEntry = new CmsAccessControlEntry(
308                    res.getResourceId(),
309                    CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_ID,
310                    allowedPermissions,
311                    deniedPermissions,
312                    flags);
313                acEntry.setFlags(CmsAccessControlEntry.ACCESS_FLAGS_ALLOTHERS);
314            } else if (principalName.equalsIgnoreCase(CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_NAME)) {
315                acEntry = new CmsAccessControlEntry(
316                    res.getResourceId(),
317                    CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_ID,
318                    allowedPermissions,
319                    deniedPermissions,
320                    flags);
321                acEntry.setFlags(CmsAccessControlEntry.ACCESS_FLAGS_OVERWRITE_ALL);
322            } else if (principalType.equalsIgnoreCase(CmsRole.PRINCIPAL_ROLE)) {
323                // only vfs managers can set role based permissions
324                m_securityManager.checkRoleForResource(m_context, CmsRole.VFS_MANAGER, res);
325                // check for role
326                CmsRole role = CmsRole.valueOfRoleName(principalName);
327                // role based permissions can only be set in the system folder
328                if (role == null) {
329                    throw e;
330                }
331                acEntry = new CmsAccessControlEntry(
332                    res.getResourceId(),
333                    role.getId(),
334                    allowedPermissions,
335                    deniedPermissions,
336                    flags);
337                acEntry.setFlags(CmsAccessControlEntry.ACCESS_FLAGS_ROLE);
338            } else {
339                throw e;
340            }
341        }
342
343        m_securityManager.writeAccessControlEntry(m_context, res, acEntry);
344    }
345
346    /**
347     * Changes the access control for a given resource and a given principal(user/group).<p>
348     *
349     * @param resourceName name of the resource
350     * @param principalType the type of the principal (group or user):
351     *      <ul>
352     *          <li><code>{@link I_CmsPrincipal#PRINCIPAL_USER}</code></li>
353     *          <li><code>{@link I_CmsPrincipal#PRINCIPAL_GROUP}</code></li>
354     *      </ul>
355     * @param principalName name of the principal
356     * @param permissionString the permissions in the format ((+|-)(r|w|v|c|i|o))*
357     *
358     * @throws CmsException if something goes wrong
359     */
360    public void chacc(String resourceName, String principalType, String principalName, String permissionString)
361    throws CmsException {
362
363        CmsResource res = readResource(resourceName, CmsResourceFilter.ALL);
364
365        CmsAccessControlEntry acEntry = null;
366        try {
367            I_CmsPrincipal principal = CmsPrincipal.readPrincipal(this, principalType, principalName);
368            acEntry = new CmsAccessControlEntry(res.getResourceId(), principal.getId(), permissionString);
369            acEntry.setFlagsForPrincipal(principal);
370        } catch (CmsDbEntryNotFoundException e) {
371            // check for special ids
372            if (principalName.equalsIgnoreCase(CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_NAME)) {
373                acEntry = new CmsAccessControlEntry(
374                    res.getResourceId(),
375                    CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_ID,
376                    permissionString);
377                acEntry.setFlags(CmsAccessControlEntry.ACCESS_FLAGS_ALLOTHERS);
378            } else if (principalName.equalsIgnoreCase(CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_NAME)) {
379                acEntry = new CmsAccessControlEntry(
380                    res.getResourceId(),
381                    CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_ID,
382                    permissionString);
383                acEntry.setFlags(CmsAccessControlEntry.ACCESS_FLAGS_OVERWRITE_ALL);
384            } else if (principalType.equalsIgnoreCase(CmsRole.PRINCIPAL_ROLE)) {
385                // only vfs managers can set role based permissions
386                m_securityManager.checkRoleForResource(m_context, CmsRole.VFS_MANAGER, res);
387                // check for role
388                CmsRole role = CmsRole.valueOfRoleName(principalName);
389                // role based permissions can only be set in the system folder
390                if (role == null) {
391                    throw e;
392                }
393                acEntry = new CmsAccessControlEntry(res.getResourceId(), role.getId(), permissionString);
394                acEntry.setFlags(CmsAccessControlEntry.ACCESS_FLAGS_ROLE);
395            } else {
396                throw e;
397            }
398        }
399
400        m_securityManager.writeAccessControlEntry(m_context, res, acEntry);
401    }
402
403    /**
404     * Changes the lock of a resource to the current user,
405     * that is "steals" the lock from another user.<p>
406     *
407     * This is the "steal lock" operation.<p>
408     *
409     * @param resource the resource to change the lock
410     *
411     * @throws CmsException if something goes wrong
412     */
413    public void changeLock(CmsResource resource) throws CmsException {
414
415        getResourceType(resource).changeLock(this, m_securityManager, resource);
416    }
417
418    /**
419     * Changes the lock of a resource to the current user,
420     * that is "steals" the lock from another user.<p>
421     *
422     * This is the "steal lock" operation.<p>
423     *
424     * @param resourcename the name of the resource to change the lock with complete path
425     *
426     * @throws CmsException if something goes wrong
427     */
428    public void changeLock(String resourcename) throws CmsException {
429
430        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
431        changeLock(resource);
432    }
433
434    /**
435     * Returns a list with all sub resources of a given folder that have set the given property,
436     * matching the current property's value with the given old value and replacing it by a given new value.<p>
437     *
438     * @param resourcename the name of the resource to change the property value
439     * @param property the name of the property to change the value
440     * @param oldValue the old value of the property, can be a regular expression
441     * @param newValue the new value of the property
442     * @param recursive if true, change recursively all property values on sub-resources (only for folders)
443     *
444     * @return a list with the <code>{@link CmsResource}</code>'s where the property value has been changed
445     *
446     * @throws CmsException if operation was not successful
447     */
448    public List<CmsResource> changeResourcesInFolderWithProperty(
449        String resourcename,
450        String property,
451        String oldValue,
452        String newValue,
453        boolean recursive)
454    throws CmsException {
455
456        CmsResource resource = readResource(resourcename, CmsResourceFilter.IGNORE_EXPIRATION);
457        return m_securityManager.changeResourcesInFolderWithProperty(
458            m_context,
459            resource,
460            property,
461            oldValue,
462            newValue,
463            recursive);
464    }
465
466    /**
467     * Changes the resource flags of a resource.<p>
468     *
469     * The resource flags are used to indicate various "special" conditions
470     * for a resource. Most notably, the "internal only" setting which signals
471     * that a resource can not be directly requested with it's URL.<p>
472     *
473     * @param resourcename the name of the resource to change the flags for (full current site relative path)
474     * @param flags the new flags for this resource
475     *
476     * @throws CmsException if something goes wrong
477     */
478    public void chflags(String resourcename, int flags) throws CmsException {
479
480        CmsResource resource = readResource(resourcename, CmsResourceFilter.IGNORE_EXPIRATION);
481        getResourceType(resource).chflags(this, m_securityManager, resource, flags);
482    }
483
484    /**
485     * Changes the resource type of a resource.<p>
486     *
487     * OpenCms handles resources according to the resource type,
488     * not the file suffix. This is e.g. why a JSP in OpenCms can have the
489     * suffix ".html" instead of ".jsp" only. Changing the resource type
490     * makes sense e.g. if you want to make a plain text file a JSP resource,
491     * or a binary file an image, etc.<p>
492     *
493     * @param resource the resource whose type should be changed
494     * @param type the new resource type for this resource
495     *
496     * @throws CmsException if something goes wrong
497     */
498    public void chtype(CmsResource resource, I_CmsResourceType type) throws CmsException {
499
500        getResourceType(resource).chtype(this, m_securityManager, resource, type);
501    }
502
503    /**
504     * Changes the resource type of a resource.<p>
505     *
506     * OpenCms handles resources according to the resource type,
507     * not the file suffix. This is e.g. why a JSP in OpenCms can have the
508     * suffix ".html" instead of ".jsp" only. Changing the resource type
509     * makes sense e.g. if you want to make a plain text file a JSP resource,
510     * or a binary file an image, etc.<p>
511     *
512     * @param resourcename the name of the resource to change the type for (full current site relative path)
513     * @param type the new resource type for this resource
514     *
515     * @throws CmsException if something goes wrong
516     */
517    public void chtype(String resourcename, I_CmsResourceType type) throws CmsException {
518
519        CmsResource resource = readResource(resourcename, CmsResourceFilter.IGNORE_EXPIRATION);
520        getResourceType(resource).chtype(this, m_securityManager, resource, type);
521    }
522
523    /**
524     * Changes the resource type of a resource.<p>
525     *
526     * OpenCms handles resources according to the resource type,
527     * not the file suffix. This is e.g. why a JSP in OpenCms can have the
528     * suffix ".html" instead of ".jsp" only. Changing the resource type
529     * makes sense e.g. if you want to make a plain text file a JSP resource,
530     * or a binary file an image, etc.<p>
531     *
532     * @param resourcename the name of the resource to change the type for (full current site relative path)
533     * @param type the new resource type for this resource
534     *
535     * @throws CmsException if something goes wrong
536     *
537     * @deprecated
538     * Use {@link #chtype(String, I_CmsResourceType)} instead.
539     * Resource types should always be referenced either by its type class (preferred) or by type name.
540     * Use of int based resource type references will be discontinued in a future OpenCms release.
541     */
542    @Deprecated
543    public void chtype(String resourcename, int type) throws CmsException {
544
545        chtype(resourcename, getResourceType(type));
546    }
547
548    /**
549     * Copies a resource.<p>
550     *
551     * The copied resource will always be locked to the current user
552     * after the copy operation.<p>
553     *
554     * Siblings will be treated according to the
555     * <code>{@link org.opencms.file.CmsResource#COPY_PRESERVE_SIBLING}</code> mode.<p>
556     *
557     * @param source the name of the resource to copy (full current site relative path)
558     * @param destination the name of the copy destination (full current site relative path)
559     *
560     * @throws CmsException if something goes wrong
561     * @throws CmsIllegalArgumentException if the <code>destination</code> argument is null or of length 0
562     *
563     * @see #copyResource(String, String, CmsResource.CmsResourceCopyMode)
564     */
565    public void copyResource(String source, String destination) throws CmsException, CmsIllegalArgumentException {
566
567        copyResource(source, destination, CmsResource.COPY_PRESERVE_SIBLING);
568    }
569
570    /**
571     * Copies a resource.<p>
572     *
573     * The copied resource will always be locked to the current user
574     * after the copy operation.<p>
575     *
576     * The <code>siblingMode</code> parameter controls how to handle siblings
577     * during the copy operation.<br>
578     * Possible values for this parameter are: <br>
579     * <ul>
580     * <li><code>{@link CmsResource#COPY_AS_NEW}</code></li>
581     * <li><code>{@link CmsResource#COPY_AS_SIBLING}</code></li>
582     * <li><code>{@link CmsResource#COPY_PRESERVE_SIBLING}</code></li>
583     * </ul><p>
584     *
585     * @param source the name of the resource to copy (full current site relative path)
586     * @param destination the name of the copy destination (full current site relative path)
587     * @param siblingMode indicates how to handle siblings during copy
588     *
589     * @throws CmsException if something goes wrong
590     * @throws CmsIllegalArgumentException if the <code>destination</code> argument is null or of length 0
591     */
592    public void copyResource(String source, String destination, CmsResource.CmsResourceCopyMode siblingMode)
593    throws CmsException, CmsIllegalArgumentException {
594
595        CmsResource resource = readResource(source, CmsResourceFilter.IGNORE_EXPIRATION);
596        getResourceType(resource).copyResource(this, m_securityManager, resource, destination, siblingMode);
597    }
598
599    /**
600     * Copies a resource to the current project of the user.<p>
601     *
602     * This is used to extend the current users project with the
603     * specified resource, in case that the resource is not yet part of the project.
604     * The resource is not really copied like in a regular copy operation,
605     * it is in fact only "enabled" in the current users project.<p>
606     *
607     * @param resource the resource to copy to the current project
608     *
609     * @throws CmsException if something goes wrong
610     */
611    public void copyResourceToProject(CmsResource resource) throws CmsException {
612
613        getResourceType(resource).copyResourceToProject(this, m_securityManager, resource);
614    }
615
616    /**
617     * Copies a resource to the current project of the user.<p>
618     *
619     * This is used to extend the current users project with the
620     * specified resource, in case that the resource is not yet part of the project.
621     * The resource is not really copied like in a regular copy operation,
622     * it is in fact only "enabled" in the current users project.<p>
623     *
624     * @param resourcename the name of the resource to copy to the current project (full current site relative path)
625     *
626     * @throws CmsException if something goes wrong
627     */
628    public void copyResourceToProject(String resourcename) throws CmsException {
629
630        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
631        copyResourceToProject(resource);
632    }
633
634    /**
635     * Counts the locked resources in a project.<p>
636     *
637     * @param id the id of the project
638     *
639     * @return the number of locked resources in this project
640     *
641     * @throws CmsException if operation was not successful
642     */
643    public int countLockedResources(CmsUUID id) throws CmsException {
644
645        return m_securityManager.countLockedResources(m_context, id);
646    }
647
648    /**
649     * Copies access control entries of a given resource to another resource.<p>
650     *
651     * Already existing access control entries of the destination resource are removed.<p>
652     *
653     * @param sourceName the name of the resource of which the access control entries are copied
654     * @param destName the name of the resource to which the access control entries are applied
655     *
656     * @throws CmsException if something goes wrong
657     */
658    public void cpacc(String sourceName, String destName) throws CmsException {
659
660        CmsResource source = readResource(sourceName);
661        CmsResource dest = readResource(destName);
662        m_securityManager.copyAccessControlEntries(m_context, source, dest);
663    }
664
665    /**
666     * Creates a new user group.<p>
667     *
668     * @param groupFqn the name of the new group
669     * @param description the description of the new group
670     * @param flags the flags for the new group
671     * @param parent the parent group (or <code>null</code>)
672     *
673     * @return a <code>{@link CmsGroup}</code> object representing the newly created group
674     *
675     * @throws CmsException if operation was not successful
676     */
677    public CmsGroup createGroup(String groupFqn, String description, int flags, String parent) throws CmsException {
678
679        return m_securityManager.createGroup(m_context, groupFqn, description, flags, parent);
680    }
681
682    /**
683     * Creates a new project.<p>
684     *
685     * @param name the name of the project to create
686     * @param description the description for the new project
687     * @param groupname the name of the project user group
688     * @param managergroupname the name of the project manager group
689     *
690     * @return the created project
691     *
692     * @throws CmsException if something goes wrong
693     */
694    public CmsProject createProject(String name, String description, String groupname, String managergroupname)
695    throws CmsException {
696
697        return m_securityManager.createProject(
698            m_context,
699            name,
700            description,
701            groupname,
702            managergroupname,
703            CmsProject.PROJECT_TYPE_NORMAL);
704    }
705
706    /**
707     * Creates a new project.<p>
708     *
709     * @param name the name of the project to create
710     * @param description the description for the new project
711     * @param groupname the name of the project user group
712     * @param managergroupname the name of the project manager group
713     * @param projecttype the type of the project (normal or temporary)
714     *
715     * @return the created project
716     *
717     * @throws CmsException if operation was not successful
718     */
719    public CmsProject createProject(
720        String name,
721        String description,
722        String groupname,
723        String managergroupname,
724        CmsProject.CmsProjectType projecttype)
725    throws CmsException {
726
727        return m_securityManager.createProject(m_context, name, description, groupname, managergroupname, projecttype);
728    }
729
730    /**
731     * Creates a property definition.<p>
732     *
733     * Property definitions are valid for all resource types.<p>
734     *
735     * @param name the name of the property definition to create
736     *
737     * @return the created property definition
738     *
739     * @throws CmsException if something goes wrong
740     */
741    public CmsPropertyDefinition createPropertyDefinition(String name) throws CmsException {
742
743        return (m_securityManager.createPropertyDefinition(m_context, name));
744    }
745
746    /**
747     * Creates a resource with the given properties and content.
748     * Will throw an exception, if a resource with the given name already exists.<p>
749     *
750     * @param sitePath the site path for the resource
751     * @param resource the resource object to be imported
752     * @param content the content of the resource
753     * @param properties the properties of the resource
754     *
755     * @return the imported resource
756     *
757     * @throws CmsException if something goes wrong
758     */
759    public CmsResource createResource(
760        String sitePath,
761        CmsResource resource,
762        byte[] content,
763        List<CmsProperty> properties)
764    throws CmsException {
765
766        resource.setUserLastModified(getRequestContext().getCurrentUser().getId());
767        resource.setDateLastModified(System.currentTimeMillis());
768        // ensure resource record is updated
769        resource.setState(CmsResource.STATE_NEW);
770        return m_securityManager.createResource(
771            m_context,
772            m_context.addSiteRoot(sitePath),
773            resource,
774            content,
775            properties);
776    }
777
778    /**
779     * Creates a new resource of the given resource type with
780     * empty content and no properties.<p>
781     *
782     * @param resourcename the name of the resource to create (full current site relative path)
783     * @param type the type of the resource to create
784     *
785     * @return the created resource
786     *
787     * @throws CmsException if something goes wrong
788     * @throws CmsIllegalArgumentException if the given <code>resourcename</code> is null or of length 0
789     *
790     * @see #createResource(String, int, byte[], List)
791     */
792    public CmsResource createResource(String resourcename, I_CmsResourceType type)
793    throws CmsException, CmsIllegalArgumentException {
794
795        return createResource(resourcename, type, new byte[0], new ArrayList<CmsProperty>(0));
796    }
797
798    /**
799     * Creates a new resource of the given resource type
800     * with the provided content and properties.<p>
801     *
802     * @param resourcename the name of the resource to create (full current site relative path)
803     * @param type the type of the resource to create
804     * @param content the contents for the new resource
805     * @param properties the properties for the new resource
806     *
807     * @return the created resource
808     *
809     * @throws CmsException if something goes wrong
810     * @throws CmsIllegalArgumentException if the <code>resourcename</code> argument is null or of length 0
811     */
812    public CmsResource createResource(
813        String resourcename,
814        I_CmsResourceType type,
815        byte[] content,
816        List<CmsProperty> properties)
817    throws CmsException, CmsIllegalArgumentException {
818
819        return type.createResource(this, m_securityManager, resourcename, content, properties);
820    }
821
822    /**
823     * Creates a new resource of the given resource type with
824     * empty content and no properties.<p>
825     *
826     * @param resourcename the name of the resource to create (full current site relative path)
827     * @param type the type of the resource to create
828     *
829     * @return the created resource
830     *
831     * @throws CmsException if something goes wrong
832     * @throws CmsIllegalArgumentException if the given <code>resourcename</code> is null or of length 0
833     *
834     * @see #createResource(String, int, byte[], List)
835     *
836     * @deprecated
837     * Use {@link #createResource(String, I_CmsResourceType)} instead.
838     * Resource types should always be referenced either by its type class (preferred) or by type name.
839     * Use of int based resource type references will be discontinued in a future OpenCms release.
840     */
841    @Deprecated
842    public CmsResource createResource(String resourcename, int type) throws CmsException, CmsIllegalArgumentException {
843
844        return createResource(resourcename, getResourceType(type), new byte[0], new ArrayList<CmsProperty>(0));
845    }
846
847    /**
848     * Creates a new resource of the given resource type
849     * with the provided content and properties.<p>
850     *
851     * @param resourcename the name of the resource to create (full current site relative path)
852     * @param type the type of the resource to create
853     * @param content the contents for the new resource
854     * @param properties the properties for the new resource
855     *
856     * @return the created resource
857     *
858     * @throws CmsException if something goes wrong
859     * @throws CmsIllegalArgumentException if the <code>resourcename</code> argument is null or of length 0
860     *
861     * @deprecated
862     * Use {@link #createResource(String, I_CmsResourceType, byte[], List)} instead.
863     * Resource types should always be referenced either by its type class (preferred) or by type name.
864     * Use of int based resource type references will be discontinued in a future OpenCms release.
865     */
866    @Deprecated
867    public CmsResource createResource(String resourcename, int type, byte[] content, List<CmsProperty> properties)
868    throws CmsException, CmsIllegalArgumentException {
869
870        return createResource(resourcename, getResourceType(type), content, properties);
871    }
872
873    /**
874     * Creates a new sibling of the source resource.<p>
875     *
876     * @param source the name of the resource to create a sibling for with complete path
877     * @param destination the name of the sibling to create with complete path
878     * @param properties the individual properties for the new sibling
879     *
880     * @return the new created sibling
881     *
882     * @throws CmsException if something goes wrong
883     */
884    public CmsResource createSibling(String source, String destination, List<CmsProperty> properties)
885    throws CmsException {
886
887        CmsResource resource = readResource(source, CmsResourceFilter.IGNORE_EXPIRATION);
888        return getResourceType(resource).createSibling(this, m_securityManager, resource, destination, properties);
889    }
890
891    /**
892     * Creates the project for the temporary workplace files.<p>
893     *
894     * @return the created project for the temporary workplace files
895     *
896     * @throws CmsException if something goes wrong
897     */
898    public CmsProject createTempfileProject() throws CmsException {
899
900        return m_securityManager.createTempfileProject(m_context);
901    }
902
903    /**
904     * Creates a new user.<p>
905     *
906     * @param userFqn the name for the new user
907     * @param password the password for the new user
908     * @param description the description for the new user
909     * @param additionalInfos the additional infos for the user
910     *
911     * @return the created user
912     *
913     * @throws CmsException if something goes wrong
914     */
915    public CmsUser createUser(String userFqn, String password, String description, Map<String, Object> additionalInfos)
916    throws CmsException {
917
918        return m_securityManager.createUser(m_context, userFqn, password, description, additionalInfos);
919    }
920
921    /**
922     * Deletes all published resource entries.<p>
923     *
924     * @param linkType the type of resource deleted (0= non-parameter, 1=parameter)
925     *
926     * @throws CmsException if something goes wrong
927     */
928    public void deleteAllStaticExportPublishedResources(int linkType) throws CmsException {
929
930        m_securityManager.deleteAllStaticExportPublishedResources(m_context, linkType);
931    }
932
933    /**
934     * Deletes a group, where all permissions, users and children of the group
935     * are transfered to a replacement group.<p>
936     *
937     * @param groupId the id of the group to be deleted
938     * @param replacementId the id of the group to be transfered, can be <code>null</code>
939     *
940     * @throws CmsException if operation was not successful
941     */
942    public void deleteGroup(CmsUUID groupId, CmsUUID replacementId) throws CmsException {
943
944        m_securityManager.deleteGroup(m_context, groupId, replacementId);
945    }
946
947    /**
948     * Deletes a user group.<p>
949     *
950     * Only groups that contain no subgroups can be deleted.<p>
951     *
952     * @param group the name of the group
953     *
954     * @throws CmsException if operation was not successful
955     */
956    public void deleteGroup(String group) throws CmsException {
957
958        m_securityManager.deleteGroup(m_context, group);
959    }
960
961    /**
962     * Deletes the versions from the history tables, keeping the given number of versions per resource.<p>
963     *
964     * @param versionsToKeep number of versions to keep, is ignored if negative
965     * @param versionsDeleted number of versions to keep for deleted resources, is ignored if negative
966     * @param timeDeleted deleted resources older than this will also be deleted, is ignored if negative
967     * @param report the report for output logging
968     *
969     * @throws CmsException if operation was not successful
970     */
971    public void deleteHistoricalVersions(int versionsToKeep, int versionsDeleted, long timeDeleted, I_CmsReport report)
972    throws CmsException {
973
974        m_securityManager.deleteHistoricalVersions(m_context, versionsToKeep, versionsDeleted, timeDeleted, report);
975    }
976
977    /**
978     * Deletes the log entries matching the given filter.<p>
979     *
980     * @param filter the filter to use for deleting the log entries
981     *
982     * @throws CmsException if something goes wrong
983     *
984     * @see CmsSecurityManager#deleteLogEntries(CmsRequestContext, CmsLogFilter)
985     * @see #getLogEntries(CmsLogFilter)
986     */
987    public void deleteLogEntries(CmsLogFilter filter) throws CmsException {
988
989        m_securityManager.deleteLogEntries(m_context, filter);
990    }
991
992    /**
993     * Deletes a project.<p>
994     *
995     * All resources inside the project have to be be reset to their online state.<p>
996     *
997     * @param id the id of the project to delete
998     *
999     * @throws CmsException if operation was not successful
1000     */
1001    public void deleteProject(CmsUUID id) throws CmsException {
1002
1003        m_securityManager.deleteProject(m_context, id);
1004    }
1005
1006    /**
1007     * Deletes a property definition.<p>
1008     *
1009     * @param name the name of the property definition to delete
1010     *
1011     * @throws CmsException if something goes wrong
1012     */
1013    public void deletePropertyDefinition(String name) throws CmsException {
1014
1015        m_securityManager.deletePropertyDefinition(m_context, name);
1016    }
1017
1018    /**
1019     * Deletes the relations to a given resource.<p>
1020     *
1021     * @param resource the resource to delete the relations from
1022     * @param filter the filter to use for deleting the relations
1023     *
1024     * @throws CmsException if something goes wrong
1025     */
1026    public void deleteRelationsFromResource(CmsResource resource, CmsRelationFilter filter) throws CmsException {
1027
1028        m_securityManager.deleteRelationsForResource(m_context, resource, filter);
1029    }
1030
1031    /**
1032     * Deletes the relations to a given resource.<p>
1033     *
1034     * @param resourceName the resource to delete the relations from
1035     * @param filter the filter to use for deleting the relations
1036     *
1037     * @throws CmsException if something goes wrong
1038     */
1039    public void deleteRelationsFromResource(String resourceName, CmsRelationFilter filter) throws CmsException {
1040
1041        CmsResource resource = readResource(resourceName, CmsResourceFilter.ALL);
1042        m_securityManager.deleteRelationsForResource(m_context, resource, filter);
1043    }
1044
1045    /**
1046     * Deletes a resource.<p>
1047     *
1048     * The <code>siblingMode</code> parameter controls how to handle siblings
1049     * during the delete operation.<br>
1050     * Possible values for this parameter are: <br>
1051     * <ul>
1052     * <li><code>{@link CmsResource#DELETE_REMOVE_SIBLINGS}</code></li>
1053     * <li><code>{@link CmsResource#DELETE_PRESERVE_SIBLINGS}</code></li>
1054     * </ul><p>
1055     *
1056     * @param res the resource to delete
1057     * @param deletePreserveSiblings indicates how to handle siblings of the deleted resource
1058     *
1059     * @throws CmsException if something goes wrong
1060     */
1061    public void deleteResource(CmsResource res, CmsResourceDeleteMode deletePreserveSiblings) throws CmsException {
1062
1063        getResourceType(res).deleteResource(this, m_securityManager, res, deletePreserveSiblings);
1064    }
1065
1066    /**
1067     * Deletes a resource given its name.<p>
1068     *
1069     * The <code>siblingMode</code> parameter controls how to handle siblings
1070     * during the delete operation.<br>
1071     * Possible values for this parameter are: <br>
1072     * <ul>
1073     * <li><code>{@link CmsResource#DELETE_REMOVE_SIBLINGS}</code></li>
1074     * <li><code>{@link CmsResource#DELETE_PRESERVE_SIBLINGS}</code></li>
1075     * </ul><p>
1076     *
1077     * @param resourcename the name of the resource to delete (full current site relative path)
1078     * @param siblingMode indicates how to handle siblings of the deleted resource
1079     *
1080     * @throws CmsException if something goes wrong
1081     */
1082    public void deleteResource(String resourcename, CmsResource.CmsResourceDeleteMode siblingMode) throws CmsException {
1083
1084        // throw the exception if resource name is an empty string
1085        if (CmsStringUtil.isEmptyOrWhitespaceOnly(resourcename)) {
1086            throw new CmsVfsResourceNotFoundException(
1087                Messages.get().container(Messages.ERR_DELETE_RESOURCE_1, resourcename));
1088        }
1089
1090        CmsResource resource = readResource(resourcename, CmsResourceFilter.IGNORE_EXPIRATION);
1091        getResourceType(resource).deleteResource(this, m_securityManager, resource, siblingMode);
1092    }
1093
1094    /**
1095     * Deletes a published resource entry.<p>
1096     *
1097     * @param resourceName The name of the resource to be deleted in the static export
1098     * @param linkType the type of resource deleted (0= non-parameter, 1=parameter)
1099     * @param linkParameter the parameters of the resource
1100     *
1101     * @throws CmsException if something goes wrong
1102     */
1103    public void deleteStaticExportPublishedResource(String resourceName, int linkType, String linkParameter)
1104    throws CmsException {
1105
1106        m_securityManager.deleteStaticExportPublishedResource(m_context, resourceName, linkType, linkParameter);
1107    }
1108
1109    /**
1110     * Deletes a user.<p>
1111     *
1112     * @param userId the id of the user to be deleted
1113     *
1114     * @throws CmsException if operation was not successful
1115     */
1116    public void deleteUser(CmsUUID userId) throws CmsException {
1117
1118        m_securityManager.deleteUser(m_context, userId);
1119    }
1120
1121    /**
1122     * Deletes a user, where all permissions and resources attributes of the user
1123     * were transfered to a replacement user.<p>
1124     *
1125     * @param userId the id of the user to be deleted
1126     * @param replacementId the id of the user to be transfered, can be <code>null</code>
1127     *
1128     * @throws CmsException if operation was not successful
1129     */
1130    public void deleteUser(CmsUUID userId, CmsUUID replacementId) throws CmsException {
1131
1132        m_securityManager.deleteUser(m_context, userId, replacementId);
1133    }
1134
1135    /**
1136     * Deletes a user.<p>
1137     *
1138     * @param username the name of the user to be deleted
1139     *
1140     * @throws CmsException if operation was not successful
1141     */
1142    public void deleteUser(String username) throws CmsException {
1143
1144        m_securityManager.deleteUser(m_context, username);
1145    }
1146
1147    /**
1148     * Checks the availability of a resource in the VFS,
1149     * using the <code>{@link CmsResourceFilter#DEFAULT}</code> filter.<p>
1150     *
1151     * A resource may be of type <code>{@link CmsFile}</code> or
1152     * <code>{@link CmsFolder}</code>.<p>
1153     *
1154     * This method also takes into account the user permissions, so if
1155     * the given resource exists, but the current user has not the required
1156     * permissions, then this method will return <code>false</code>.<p>
1157     *
1158     * @param structureId the structure id of the resource to check
1159     *
1160     * @return <code>true</code> if the resource is available
1161     *
1162     * @see #readResource(CmsUUID)
1163     * @see #existsResource(CmsUUID, CmsResourceFilter)
1164     */
1165    public boolean existsResource(CmsUUID structureId) {
1166
1167        return existsResource(structureId, CmsResourceFilter.DEFAULT);
1168    }
1169
1170    /**
1171     * Checks the availability of a resource in the VFS,
1172     * using the <code>{@link CmsResourceFilter#DEFAULT}</code> filter.<p>
1173     *
1174     * A resource may be of type <code>{@link CmsFile}</code> or
1175     * <code>{@link CmsFolder}</code>.<p>
1176     *
1177     * The specified filter controls what kind of resources should be "found"
1178     * during the read operation. This will depend on the application. For example,
1179     * using <code>{@link CmsResourceFilter#DEFAULT}</code> will only return currently
1180     * "valid" resources, while using <code>{@link CmsResourceFilter#IGNORE_EXPIRATION}</code>
1181     * will ignore the date release / date expired information of the resource.<p>
1182     *
1183     * This method also takes into account the user permissions, so if
1184     * the given resource exists, but the current user has not the required
1185     * permissions, then this method will return <code>false</code>.<p>
1186     *
1187     * @param structureId the structure id of the resource to check
1188     * @param filter the resource filter to use while checking
1189     *
1190     * @return <code>true</code> if the resource is available
1191     *
1192     * @see #readResource(CmsUUID)
1193     * @see #readResource(CmsUUID, CmsResourceFilter)
1194     */
1195    public boolean existsResource(CmsUUID structureId, CmsResourceFilter filter) {
1196
1197        return m_securityManager.existsResource(m_context, structureId, filter);
1198    }
1199
1200    /**
1201     * Checks the availability of a resource in the VFS,
1202     * using the <code>{@link CmsResourceFilter#DEFAULT}</code> filter.<p>
1203     *
1204     * A resource may be of type <code>{@link CmsFile}</code> or
1205     * <code>{@link CmsFolder}</code>.<p>
1206     *
1207     * This method also takes into account the user permissions, so if
1208     * the given resource exists, but the current user has not the required
1209     * permissions, then this method will return <code>false</code>.<p>
1210     *
1211     * @param resourcename the name of the resource to check (full current site relative path)
1212     *
1213     * @return <code>true</code> if the resource is available
1214     *
1215     * @see #readResource(String)
1216     * @see #existsResource(String, CmsResourceFilter)
1217     */
1218    public boolean existsResource(String resourcename) {
1219
1220        return existsResource(resourcename, CmsResourceFilter.DEFAULT);
1221    }
1222
1223    /**
1224     * Checks the availability of a resource in the VFS,
1225     * using the provided filter.<p>
1226     *
1227     * A resource may be of type <code>{@link CmsFile}</code> or
1228     * <code>{@link CmsFolder}</code>.<p>
1229     *
1230     * The specified filter controls what kind of resources should be "found"
1231     * during the read operation. This will depend on the application. For example,
1232     * using <code>{@link CmsResourceFilter#DEFAULT}</code> will only return currently
1233     * "valid" resources, while using <code>{@link CmsResourceFilter#IGNORE_EXPIRATION}</code>
1234     * will ignore the date release / date expired information of the resource.<p>
1235     *
1236     * This method also takes into account the user permissions, so if
1237     * the given resource exists, but the current user has not the required
1238     * permissions, then this method will return <code>false</code>.<p>
1239     *
1240     * @param resourcename the name of the resource to check (full current site relative path)
1241     * @param filter the resource filter to use while checking
1242     *
1243     * @return <code>true</code> if the resource is available
1244     *
1245     * @see #readResource(String)
1246     * @see #readResource(String, CmsResourceFilter)
1247     */
1248    public boolean existsResource(String resourcename, CmsResourceFilter filter) {
1249
1250        return m_securityManager.existsResource(m_context, addSiteRoot(resourcename), filter);
1251    }
1252
1253    /**
1254     * Returns the list of access control entries of a resource given its name.<p>
1255     *
1256     * @param resourceName the name of the resource
1257     *
1258     * @return a list of <code>{@link CmsAccessControlEntry}</code> objects
1259     *
1260     * @throws CmsException if something goes wrong
1261     */
1262    public List<CmsAccessControlEntry> getAccessControlEntries(String resourceName) throws CmsException {
1263
1264        return getAccessControlEntries(resourceName, true);
1265    }
1266
1267    /**
1268     * Returns the list of access control entries of a resource given its name.<p>
1269     *
1270     * @param resourceName the name of the resource
1271     * @param getInherited <code>true</code>, if inherited access control entries should be returned, too
1272     *
1273     * @return a list of <code>{@link CmsAccessControlEntry}</code> objects defining all permissions for the given resource
1274     *
1275     * @throws CmsException if something goes wrong
1276     */
1277    public List<CmsAccessControlEntry> getAccessControlEntries(String resourceName, boolean getInherited)
1278    throws CmsException {
1279
1280        CmsResource res = readResource(resourceName, CmsResourceFilter.ALL);
1281        return m_securityManager.getAccessControlEntries(m_context, res, getInherited);
1282    }
1283
1284    /**
1285     * Returns the access control list (summarized access control entries) of a given resource.<p>
1286     *
1287     * @param resourceName the name of the resource
1288     *
1289     * @return the access control list of the resource
1290     *
1291     * @throws CmsException if something goes wrong
1292     */
1293    public CmsAccessControlList getAccessControlList(String resourceName) throws CmsException {
1294
1295        return getAccessControlList(resourceName, false);
1296    }
1297
1298    /**
1299     * Returns the access control list (summarized access control entries) of a given resource.<p>
1300     *
1301     * If <code>inheritedOnly</code> is set, only inherited access control entries are returned.<p>
1302     *
1303     * @param resourceName the name of the resource
1304     * @param inheritedOnly if set, the non-inherited entries are skipped
1305     *
1306     * @return the access control list of the resource
1307     *
1308     * @throws CmsException if something goes wrong
1309     */
1310    public CmsAccessControlList getAccessControlList(String resourceName, boolean inheritedOnly) throws CmsException {
1311
1312        CmsResource res = readResource(resourceName, CmsResourceFilter.ALL);
1313        return m_securityManager.getAccessControlList(m_context, res, inheritedOnly);
1314    }
1315
1316    /**
1317     * Gets all access control entries for the current project.<p>
1318     *
1319     * @return the list of all access control entries
1320     *
1321     * @throws CmsException if something goes wrong
1322     */
1323    public List<CmsAccessControlEntry> getAllAccessControlEntries() throws CmsException {
1324
1325        return m_securityManager.getAllAccessControlEntries(m_context);
1326    }
1327
1328    /**
1329     * Returns a list with all projects from history.<p>
1330     *
1331     * @return list of <code>{@link CmsHistoryProject}</code> objects
1332     *           with all projects from history
1333     *
1334     * @throws CmsException  if operation was not successful
1335     */
1336    public List<CmsHistoryProject> getAllHistoricalProjects() throws CmsException {
1337
1338        return m_securityManager.getAllHistoricalProjects(m_context);
1339    }
1340
1341    /**
1342     * Gets all URL names for a given structure id.<p>
1343     *
1344     * @param id the structure id
1345     * @return the list of all URL names for that structure id
1346     *
1347     * @throws CmsException if something goes wrong
1348     */
1349    public List<String> getAllUrlNames(CmsUUID id) throws CmsException {
1350
1351        return m_securityManager.readAllUrlNameMappingEntries(m_context, id);
1352    }
1353
1354    /**
1355     * Returns a list of child resources to the given resource that can not be locked by the current user.<p>
1356     *
1357     * @param resource the resource
1358     *
1359     * @return a list of child resources to the given resource that can not be locked by the current user
1360     *
1361     * @throws CmsException if something goes wrong reading the resources
1362     */
1363    public List<CmsResource> getBlockingLockedResources(CmsResource resource) throws CmsException {
1364
1365        if (resource.isFolder()) {
1366            CmsLockFilter blockingFilter = CmsLockFilter.FILTER_NON_INHERITED;
1367            blockingFilter = blockingFilter.filterNotLockableByUser(getRequestContext().getCurrentUser());
1368            return getLockedResources(resource, blockingFilter);
1369        }
1370        return Collections.<CmsResource> emptyList();
1371    }
1372
1373    /**
1374     * Returns a list of child resources to the given resource that can not be locked by the current user.<p>
1375     *
1376     * @param resourceName the resource site path
1377     *
1378     * @return a list of child resources to the given resource that can not be locked by the current user
1379     *
1380     * @throws CmsException if something goes wrong reading the resources
1381     */
1382    public List<CmsResource> getBlockingLockedResources(String resourceName) throws CmsException {
1383
1384        CmsResource resource = readResource(resourceName);
1385        return getBlockingLockedResources(resource);
1386    }
1387
1388    /**
1389     * Returns all child groups of a group.<p>
1390     *
1391     * @param groupname the name of the group
1392     * @param includeSubChildren if set also returns all sub-child groups of the given group
1393     *
1394     * @return a list of all child <code>{@link CmsGroup}</code> objects or <code>null</code>
1395     *
1396     * @throws CmsException if operation was not successful
1397     */
1398    public List<CmsGroup> getChildren(String groupname, boolean includeSubChildren) throws CmsException {
1399
1400        return m_securityManager.getChildren(m_context, groupname, includeSubChildren);
1401    }
1402
1403    /**
1404     * Returns the detail name of a resource.<p>
1405     *
1406     * The detail view URI of a content element consists of its detail page URI and the detail name returned by this
1407     * method.<p>
1408     *
1409     * @param res the resource for which the detail name should be retrieved
1410     * @param locale the locale for the detail name
1411     * @param defaultLocales the default locales for the detail name
1412     *
1413     * @return the detail name
1414     * @throws CmsException if something goes wrong
1415     */
1416    public String getDetailName(CmsResource res, Locale locale, List<Locale> defaultLocales) throws CmsException {
1417
1418        String urlName = readBestUrlName(res.getStructureId(), locale, defaultLocales);
1419        if (urlName == null) {
1420            urlName = res.getStructureId().toString();
1421        }
1422        return urlName;
1423    }
1424
1425    /**
1426     * Returns all file resources contained in a folder.<p>
1427     *
1428     * The result is filtered according to the rules of
1429     * the <code>{@link CmsResourceFilter#DEFAULT}</code> filter.<p>
1430     *
1431     * @param resourcename the full current site relative path of the resource to return the child resources for
1432     *
1433     * @return a list of all child files as <code>{@link CmsResource}</code> objects
1434     *
1435     * @throws CmsException if something goes wrong
1436     *
1437     * @see #getFilesInFolder(String, CmsResourceFilter)
1438     */
1439    public List<CmsResource> getFilesInFolder(String resourcename) throws CmsException {
1440
1441        return getFilesInFolder(resourcename, CmsResourceFilter.DEFAULT);
1442    }
1443
1444    /**
1445     * Returns all file resources contained in a folder.<p>
1446     *
1447     * With the <code>{@link CmsResourceFilter}</code> provided as parameter
1448     * you can control if you want to include deleted, invisible or
1449     * time-invalid resources in the result.<p>
1450     *
1451     * @param resourcename the full path of the resource to return the child resources for
1452     * @param filter the resource filter to use
1453     *
1454     * @return a list of all child file as <code>{@link CmsResource}</code> objects
1455     *
1456     * @throws CmsException if something goes wrong
1457     */
1458    public List<CmsResource> getFilesInFolder(String resourcename, CmsResourceFilter filter) throws CmsException {
1459
1460        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
1461        return m_securityManager.readChildResources(m_context, resource, filter, false, true);
1462    }
1463
1464    /**
1465     * Returns all the groups the given user belongs to.<p>
1466     *
1467     * @param username the name of the user
1468     * @param directGroupsOnly if set only the direct assigned groups will be returned, if not also indirect roles
1469     *
1470     * @return a list of <code>{@link CmsGroup}</code> objects
1471     *
1472     * @throws CmsException if operation was not successful
1473     */
1474    public List<CmsGroup> getGroupsOfUser(String username, boolean directGroupsOnly) throws CmsException {
1475
1476        return getGroupsOfUser(username, directGroupsOnly, true);
1477    }
1478
1479    /**
1480     * Returns all the groups the given user belongs to.<p>
1481     *
1482     * @param username the name of the user
1483     * @param directGroupsOnly if set only the direct assigned groups will be returned, if not also indirect roles
1484     * @param includeOtherOus if to include groups of other organizational units
1485     *
1486     * @return a list of <code>{@link CmsGroup}</code> objects
1487     *
1488     * @throws CmsException if operation was not successful
1489     */
1490    public List<CmsGroup> getGroupsOfUser(String username, boolean directGroupsOnly, boolean includeOtherOus)
1491    throws CmsException {
1492
1493        return getGroupsOfUser(username, directGroupsOnly, includeOtherOus, m_context.getRemoteAddress());
1494    }
1495
1496    /**
1497     * Returns the groups of a user filtered by the specified IP address.<p>
1498     *
1499     * @param username the name of the user
1500     * @param directGroupsOnly if set only the direct assigned groups will be returned, if not also indirect roles
1501     * @param remoteAddress the IP address to filter the groups in the result list
1502     * @param includeOtherOus if to include groups of other organizational units
1503     *
1504     * @return a list of <code>{@link CmsGroup}</code> objects filtered by the specified IP address
1505     *
1506     * @throws CmsException if operation was not successful
1507     */
1508    public List<CmsGroup> getGroupsOfUser(
1509        String username,
1510        boolean directGroupsOnly,
1511        boolean includeOtherOus,
1512        String remoteAddress)
1513    throws CmsException {
1514
1515        return m_securityManager.getGroupsOfUser(
1516            m_context,
1517            username,
1518            (includeOtherOus ? "" : CmsOrganizationalUnit.getParentFqn(username)),
1519            includeOtherOus,
1520            false,
1521            directGroupsOnly,
1522            remoteAddress);
1523    }
1524
1525    /**
1526     * Creates a new locale group service.<p>
1527     *
1528     * @return a locale group service instance
1529     */
1530    public CmsLocaleGroupService getLocaleGroupService() {
1531
1532        return new CmsLocaleGroupService(this);
1533    }
1534
1535    /**
1536     * Returns the edition lock state for a specified resource.<p>
1537     *
1538     * If the resource is waiting to be publish you might get a lock of type {@link CmsLockType#PUBLISH}.<p>
1539     *
1540     * @param resource the resource to return the edition lock state for
1541     *
1542     * @return the edition lock state for the specified resource
1543     *
1544     * @throws CmsException if something goes wrong
1545     */
1546    public CmsLock getLock(CmsResource resource) throws CmsException {
1547
1548        return m_securityManager.getLock(m_context, resource);
1549    }
1550
1551    /**
1552     * Returns the lock state for a specified resource name.<p>
1553     *
1554     * If the resource is waiting to be publish you might get a lock of type {@link CmsLockType#PUBLISH}.<p>
1555     *
1556     * @param resourcename the name if the resource to get the lock state for (full current site relative path)
1557     *
1558     * @return the lock state for the specified resource
1559     *
1560     * @throws CmsException if something goes wrong
1561     */
1562    public CmsLock getLock(String resourcename) throws CmsException {
1563
1564        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
1565        return getLock(resource);
1566    }
1567
1568    /**
1569     * Returns all locked resources within a folder or matches the lock of the given resource.<p>
1570     *
1571     * @param resource the resource to check
1572     * @param filter the lock filter
1573     *
1574     * @return a list of locked resources
1575     *
1576     * @throws CmsException if operation was not successful
1577     */
1578    public List<CmsResource> getLockedResources(CmsResource resource, CmsLockFilter filter) throws CmsException {
1579
1580        return m_securityManager.getLockedResourcesObjects(m_context, resource, filter);
1581    }
1582
1583    /**
1584     * Returns all locked resources within a folder or matches the lock of the given resource.<p>
1585     *
1586     * @param resourceName the name of the resource to check
1587     * @param filter the lock filter
1588     *
1589     * @return a list of locked resource paths (relative to current site)
1590     *
1591     * @throws CmsException if operation was not successful
1592     */
1593    public List<String> getLockedResources(String resourceName, CmsLockFilter filter) throws CmsException {
1594
1595        CmsResource resource = readResource(resourceName, CmsResourceFilter.ALL);
1596        return m_securityManager.getLockedResources(m_context, resource, filter);
1597    }
1598
1599    /**
1600     * Returns all locked resources within a folder or matches the lock of the given resource, but uses a cache for resource lookup.<p>
1601     *
1602     * @param resource the resource to check
1603     * @param filter the lock filter
1604     * @param cache the cache to use for resource lookups
1605     *
1606     * @return a list of locked resources
1607     *
1608     * @throws CmsException if operation was not successful
1609     */
1610    public List<CmsResource> getLockedResourcesWithCache(
1611        CmsResource resource,
1612        CmsLockFilter filter,
1613        Map<String, CmsResource> cache)
1614    throws CmsException {
1615
1616        return m_securityManager.getLockedResourcesObjectsWithCache(m_context, resource, filter, cache);
1617    }
1618
1619    /**
1620     * Returns all log entries matching the given filter.<p>
1621     *
1622     * @param filter the filter to match the relation
1623     *
1624     * @return a list containing all log entries matching the given filter
1625     *
1626     * @throws CmsException if something goes wrong
1627     *
1628     * @see CmsSecurityManager#getLogEntries(CmsRequestContext, CmsLogFilter)
1629     * @see #deleteLogEntries(CmsLogFilter)
1630     */
1631    public List<CmsLogEntry> getLogEntries(CmsLogFilter filter) throws CmsException {
1632
1633        return m_securityManager.getLogEntries(m_context, filter);
1634    }
1635
1636    /**
1637     * Returns the name a resource would have if it were moved to the
1638     * "lost and found" folder. <p>
1639     *
1640     * In general, it is the same name as the given resource has, the only exception is
1641     * if a resource in the "lost and found" folder with the same name already exists.
1642     * In such case, a counter is added to the resource name.<p>
1643     *
1644     * @param resourcename the name of the resource to get the "lost and found" name for (full current site relative path)
1645     *
1646     * @return the tentative name of the resource inside the "lost and found" folder
1647     *
1648     * @throws CmsException if something goes wrong
1649     *
1650     * @see #moveToLostAndFound(String)
1651     */
1652    public String getLostAndFoundName(String resourcename) throws CmsException {
1653
1654        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
1655        return m_securityManager.moveToLostAndFound(m_context, resource, true);
1656    }
1657
1658    /**
1659     * Returns the parent group of a group.<p>
1660     *
1661     * @param groupname the name of the group
1662     *
1663     * @return group the parent group or <code>null</code>
1664     *
1665     * @throws CmsException if operation was not successful
1666     */
1667    public CmsGroup getParent(String groupname) throws CmsException {
1668
1669        return m_securityManager.getParent(m_context, groupname);
1670    }
1671
1672    /**
1673     * Returns the set of permissions of the current user for a given resource.<p>
1674     *
1675     * @param resourceName the name of the resource
1676     *
1677     * @return the bit set of the permissions of the current user
1678     *
1679     * @throws CmsException if something goes wrong
1680     */
1681    public CmsPermissionSet getPermissions(String resourceName) throws CmsException {
1682
1683        return getPermissions(resourceName, m_context.getCurrentUser().getName());
1684    }
1685
1686    /**
1687     * Returns the set of permissions of a given user for a given resource.<p>
1688     *
1689     * @param resourceName the name of the resource
1690     * @param userName the name of the user
1691     *
1692     * @return the current permissions on this resource
1693     *
1694     * @throws CmsException if something goes wrong
1695     */
1696    public CmsPermissionSet getPermissions(String resourceName, String userName) throws CmsException {
1697
1698        // reading permissions is allowed even if the resource is marked as deleted
1699        CmsResource resource = readResource(resourceName, CmsResourceFilter.ALL);
1700        CmsUser user = readUser(userName);
1701        return m_securityManager.getPermissions(m_context, resource, user);
1702    }
1703
1704    /**
1705     * Returns all relations for the given resource matching the given filter.<p>
1706     *
1707     * You should have view/read permissions on the given resource.<p>
1708     *
1709     * You may become source and/or target paths to resource you do not have view/read permissions on.<p>
1710     *
1711     * @param resource the resource to retrieve the relations for
1712     * @param filter the filter to match the relation
1713     *
1714     * @return a List containing all {@link org.opencms.relations.CmsRelation}
1715     *          objects for the given resource matching the given filter
1716     *
1717     * @throws CmsException if something goes wrong
1718     *
1719     * @see CmsSecurityManager#getRelationsForResource(CmsRequestContext, CmsResource, CmsRelationFilter)
1720     */
1721    public List<CmsRelation> getRelationsForResource(CmsResource resource, CmsRelationFilter filter)
1722    throws CmsException {
1723
1724        return m_securityManager.getRelationsForResource(m_context, resource, filter);
1725    }
1726
1727    /**
1728     * Returns all relations for the given resource matching the given filter.<p>
1729     *
1730     * You should have view/read permissions on the given resource.<p>
1731     *
1732     * You may become source and/or target paths to resource you do not have view/read permissions on.<p>
1733     *
1734     * @param resourceName the name of the resource to retrieve the relations for
1735     * @param filter the filter to match the relation
1736     *
1737     * @return a List containing all {@link org.opencms.relations.CmsRelation}
1738     *          objects for the given resource matching the given filter
1739     *
1740     * @throws CmsException if something goes wrong
1741     *
1742     * @see CmsSecurityManager#getRelationsForResource(CmsRequestContext, CmsResource, CmsRelationFilter)
1743     */
1744    public List<CmsRelation> getRelationsForResource(String resourceName, CmsRelationFilter filter)
1745    throws CmsException {
1746
1747        return getRelationsForResource(readResource(resourceName, CmsResourceFilter.ALL), filter);
1748    }
1749
1750    /**
1751     * Returns the current users request context.<p>
1752     *
1753     * This request context is used to authenticate the user for all
1754     * OpenCms operations. It also contains the request runtime settings, e.g.
1755     * about the current site this request was made on.<p>
1756     *
1757     * @return the current users request context
1758     */
1759    public CmsRequestContext getRequestContext() {
1760
1761        return m_context;
1762    }
1763
1764    /**
1765     * Returns all resources associated to a given principal via an ACE with the given permissions.<p>
1766     *
1767     * If the <code>includeAttr</code> flag is set it returns also all resources associated to
1768     * a given principal through some of following attributes.<p>
1769     *
1770     * <ul>
1771     *    <li>User Created</li>
1772     *    <li>User Last Modified</li>
1773     * </ul><p>
1774     *
1775     * @param principalId the id of the principal
1776     * @param permissions a set of permissions to match, can be <code>null</code> for all ACEs
1777     * @param includeAttr a flag to include resources associated by attributes
1778     *
1779     * @return a set of <code>{@link CmsResource}</code> objects
1780     *
1781     * @throws CmsException if something goes wrong
1782     */
1783    public Set<CmsResource> getResourcesForPrincipal(
1784        CmsUUID principalId,
1785        CmsPermissionSet permissions,
1786        boolean includeAttr)
1787    throws CmsException {
1788
1789        return m_securityManager.getResourcesForPrincipal(getRequestContext(), principalId, permissions, includeAttr);
1790    }
1791
1792    /**
1793     * Returns all child resources of a resource, that is the resources
1794     * contained in a folder.<p>
1795     *
1796     * With the <code>{@link CmsResourceFilter}</code> provided as parameter
1797     * you can control if you want to include deleted, invisible or
1798     * time-invalid resources in the result.<p>
1799     *
1800     * This method is mainly used by the workplace explorer.<p>
1801     *
1802     * @param resourcename the full current site relative path of the resource to return the child resources for
1803     * @param filter the resource filter to use
1804     *
1805     * @return a list of all child <code>{@link CmsResource}</code>s
1806     *
1807     * @throws CmsException if something goes wrong
1808     */
1809    public List<CmsResource> getResourcesInFolder(String resourcename, CmsResourceFilter filter) throws CmsException {
1810
1811        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
1812        return m_securityManager.readChildResources(m_context, resource, filter, true, true);
1813    }
1814
1815    /**
1816     * Adjusts the absolute resource root path for the current site.<p>
1817     *
1818     * The full root path of a resource is always available using
1819     * <code>{@link CmsResource#getRootPath()}</code>. From this name this method cuts
1820     * of the current site root using
1821     * <code>{@link CmsRequestContext#removeSiteRoot(String)}</code>.<p>
1822     *
1823     * If the resource root path does not start with the current site root,
1824     * it is left untouched.<p>
1825     *
1826     * @param resource the resource to get the adjusted site root path for
1827     *
1828     * @return the absolute resource path adjusted for the current site
1829     *
1830     * @see CmsRequestContext#removeSiteRoot(String)
1831     * @see CmsRequestContext#getSitePath(CmsResource)
1832     * @see CmsResource#getRootPath()
1833     */
1834    public String getSitePath(CmsResource resource) {
1835
1836        return m_context.getSitePath(resource);
1837    }
1838
1839    /**
1840     * Returns all folder resources contained in a folder.<p>
1841     *
1842     * The result is filtered according to the rules of
1843     * the <code>{@link CmsResourceFilter#DEFAULT}</code> filter.<p>
1844     *
1845     * @param resourcename the full current site relative path of the resource to return the child resources for.
1846     *
1847     * @return a list of all child file as <code>{@link CmsResource}</code> objects
1848     *
1849     * @throws CmsException if something goes wrong
1850     *
1851     * @see #getSubFolders(String, CmsResourceFilter)
1852     */
1853    public List<CmsResource> getSubFolders(String resourcename) throws CmsException {
1854
1855        return getSubFolders(resourcename, CmsResourceFilter.DEFAULT);
1856    }
1857
1858    /**
1859     * Returns all folder resources contained in a folder.<p>
1860     *
1861     * With the <code>{@link CmsResourceFilter}</code> provided as parameter
1862     * you can control if you want to include deleted, invisible or
1863     * time-invalid resources in the result.<p>
1864     *
1865     * @param resourcename the full current site relative path of the resource to return the child resources for.
1866     *
1867     * @return a list of all child folder <code>{@link CmsResource}</code>s
1868     * @param filter the resource filter to use
1869     *
1870     * @throws CmsException if something goes wrong
1871     */
1872    public List<CmsResource> getSubFolders(String resourcename, CmsResourceFilter filter) throws CmsException {
1873
1874        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
1875        return m_securityManager.readChildResources(m_context, resource, filter, true, false);
1876    }
1877
1878    /**
1879     * Returns the newest URL names for the given structure id for each locale.<p>
1880     *
1881     * @param id the structure id
1882     * @return the list of URL names for each locale
1883     *
1884     * @throws CmsException if something goes wrong
1885     */
1886    public List<String> getUrlNamesForAllLocales(CmsUUID id) throws CmsException {
1887
1888        return m_securityManager.readUrlNamesForAllLocales(m_context, id);
1889    }
1890
1891    /**
1892     * Returns all direct users of a given group.<p>
1893     *
1894     * Users that are "indirectly" in the group are not returned in the result.<p>
1895     *
1896     * @param groupname the name of the group to get all users for
1897     *
1898     * @return all <code>{@link CmsUser}</code> objects in the group
1899     *
1900     * @throws CmsException if operation was not successful
1901     */
1902    public List<CmsUser> getUsersOfGroup(String groupname) throws CmsException {
1903
1904        return getUsersOfGroup(groupname, true);
1905    }
1906
1907    /**
1908     * Returns all direct users of a given group.<p>
1909     *
1910     * Users that are "indirectly" in the group are not returned in the result.<p>
1911     *
1912     * @param groupname the name of the group to get all users for
1913     * @param includeOtherOus if the result should include users of other ous
1914     *
1915     * @return all <code>{@link CmsUser}</code> objects in the group
1916     *
1917     * @throws CmsException if operation was not successful
1918     */
1919    public List<CmsUser> getUsersOfGroup(String groupname, boolean includeOtherOus) throws CmsException {
1920
1921        return m_securityManager.getUsersOfGroup(m_context, groupname, includeOtherOus, true, false);
1922    }
1923
1924    /**
1925     * Checks if the current user has required permissions to access a given resource.<p>
1926     *
1927     * @param resource the resource to check the permissions for
1928     * @param requiredPermissions the set of permissions to check for
1929     *
1930     * @return <code>true</code> if the required permissions are satisfied
1931     *
1932     * @throws CmsException if something goes wrong
1933     */
1934    public boolean hasPermissions(CmsResource resource, CmsPermissionSet requiredPermissions) throws CmsException {
1935
1936        return m_securityManager.hasPermissions(
1937            m_context,
1938            resource,
1939            requiredPermissions,
1940            true,
1941            CmsResourceFilter.ALL).isAllowed();
1942    }
1943
1944    /**
1945     * Checks if the current user has required permissions to access a given resource.<p>
1946     *
1947     * @param resource the resource to check the permissions for
1948     * @param requiredPermissions the set of permissions to check for
1949     * @param checkLock if <code>true</code> the lock status of the resource is checked for write operations
1950     *      and the resource needs be locked by the current user so that the test is passed,
1951     *      if <code>false</code> the lock is not checked at all
1952     * @param filter the resource filter to use
1953     *
1954     * @return <code>true</code> if the required permissions are satisfied
1955     *
1956     * @throws CmsException if something goes wrong
1957     */
1958    public boolean hasPermissions(
1959        CmsResource resource,
1960        CmsPermissionSet requiredPermissions,
1961        boolean checkLock,
1962        CmsResourceFilter filter)
1963    throws CmsException {
1964
1965        return I_CmsPermissionHandler.PERM_ALLOWED == m_securityManager.hasPermissions(
1966            m_context,
1967            resource,
1968            requiredPermissions,
1969            checkLock,
1970            filter);
1971    }
1972
1973    /**
1974     * Writes a list of access control entries as new access control entries of a given resource.<p>
1975     *
1976     * Already existing access control entries of this resource are removed before.<p>
1977     *
1978     * @param resource the resource to attach the control entries to
1979     * @param acEntries a list of <code>{@link CmsAccessControlEntry}</code> objects
1980     *
1981     * @throws CmsException if something goes wrong
1982     */
1983    public void importAccessControlEntries(CmsResource resource, List<CmsAccessControlEntry> acEntries)
1984    throws CmsException {
1985
1986        m_securityManager.importAccessControlEntries(m_context, resource, acEntries);
1987    }
1988
1989    /**
1990     * Imports a new relation to the given resource.<p>
1991     *
1992     * @param resourceName the name of the source resource
1993     * @param targetPath the path of the target resource
1994     * @param relationType the type of the relation
1995     *
1996     * @throws CmsException if something goes wrong
1997     */
1998    public void importRelation(String resourceName, String targetPath, String relationType) throws CmsException {
1999
2000        createRelation(resourceName, targetPath, relationType, true);
2001    }
2002
2003    /**
2004     * Imports a resource to the OpenCms VFS.<p>
2005     *
2006     * If a resource already exists in the VFS (i.e. has the same name and
2007     * same id) it is replaced by the imported resource.<p>
2008     *
2009     * If a resource with the same name but a different id exists,
2010     * the imported resource is (usually) moved to the "lost and found" folder.<p>
2011     *
2012     * @param resourcename the name for the resource after import (full current site relative path)
2013     * @param resource the resource object to be imported
2014     * @param content the content of the resource
2015     * @param properties the properties of the resource
2016     *
2017     * @return the imported resource
2018     *
2019     * @throws CmsException if something goes wrong
2020     *
2021     * @see CmsObject#moveToLostAndFound(String)
2022     */
2023    public CmsResource importResource(
2024        String resourcename,
2025        CmsResource resource,
2026        byte[] content,
2027        List<CmsProperty> properties)
2028    throws CmsException {
2029
2030        return getResourceType(
2031            resource).importResource(this, m_securityManager, resourcename, resource, content, properties);
2032    }
2033
2034    /**
2035     * Creates a new user by import.<p>
2036     *
2037     * @param id the id of the user
2038     * @param name the new name for the user
2039     * @param password the new password for the user
2040     * @param firstname the first name of the user
2041     * @param lastname the last name of the user
2042     * @param email the email of the user
2043     * @param flags the flags for a user (for example <code>{@link I_CmsPrincipal#FLAG_ENABLED}</code>)
2044     * @param dateCreated the creation date
2045     * @param additionalInfos the additional user infos
2046     *
2047     * @return the imported user
2048     *
2049     * @throws CmsException if something goes wrong
2050     */
2051    public CmsUser importUser(
2052        String id,
2053        String name,
2054        String password,
2055        String firstname,
2056        String lastname,
2057        String email,
2058        int flags,
2059        long dateCreated,
2060        Map<String, Object> additionalInfos)
2061    throws CmsException {
2062
2063        return m_securityManager.importUser(
2064            m_context,
2065            id,
2066            name,
2067            password,
2068            firstname,
2069            lastname,
2070            email,
2071            flags,
2072            dateCreated,
2073            additionalInfos);
2074    }
2075
2076    /**
2077     * Increments a counter and returns its old value.<p>
2078     *
2079     * @param name the name of the counter
2080     *
2081     * @return the value of the counter before incrementing
2082     *
2083     * @throws CmsException if something goes wrong
2084     */
2085    public int incrementCounter(String name) throws CmsException {
2086
2087        return m_securityManager.incrementCounter(m_context, name);
2088    }
2089
2090    /**
2091     * Checks if the specified resource is inside the current project.<p>
2092     *
2093     * The project "view" is determined by a set of path prefixes.
2094     * If the resource starts with any one of this prefixes, it is considered to
2095     * be "inside" the project.<p>
2096     *
2097     * @param resourcename the specified resource name (full current site relative path)
2098     *
2099     * @return <code>true</code>, if the specified resource is inside the current project
2100     */
2101    public boolean isInsideCurrentProject(String resourcename) {
2102
2103        return m_securityManager.isInsideCurrentProject(m_context, addSiteRoot(resourcename));
2104    }
2105
2106    /**
2107     * Checks if the current user has management access to the current project.<p>
2108     *
2109     * @return <code>true</code>, if the user has management access to the current project
2110     */
2111
2112    public boolean isManagerOfProject() {
2113
2114        return m_securityManager.isManagerOfProject(m_context);
2115    }
2116
2117    /**
2118     * Locks a resource.<p>
2119     *
2120     * This will be an exclusive, persistent lock that is removed only if the user unlocks it.<p>
2121     *
2122     * @param resource the resource to lock
2123     *
2124     * @throws CmsException if something goes wrong
2125     */
2126    public void lockResource(CmsResource resource) throws CmsException {
2127
2128        getResourceType(resource).lockResource(this, m_securityManager, resource, CmsLockType.EXCLUSIVE);
2129    }
2130
2131    /**
2132     * Locks a resource.<p>
2133     *
2134     * This will be an exclusive, persistent lock that is removed only if the user unlocks it.<p>
2135     *
2136     * @param resourcename the name of the resource to lock (full current site relative path)
2137     *
2138     * @throws CmsException if something goes wrong
2139     */
2140    public void lockResource(String resourcename) throws CmsException {
2141
2142        lockResource(resourcename, CmsLockType.EXCLUSIVE);
2143    }
2144
2145    /**
2146     * Locks the given resource with a shallow lock that is not inherited on subresources.
2147     *
2148     * <p>Shallow locks are non-persistent, like temporary locks.
2149     *
2150     * @param resource the resource to lock
2151     * @throws CmsException if something goes wrong
2152     */
2153    public void lockResourceShallow(CmsResource resource) throws CmsException {
2154
2155        getResourceType(resource).lockResource(this, m_securityManager, resource, CmsLockType.SHALLOW);
2156    }
2157
2158    /**
2159     * Locks a resource temporary.<p>
2160     *
2161     * This will be an exclusive, temporary lock valid only for the current users session.
2162     * Usually this should not be used directly, this method is intended for the OpenCms workplace only.<p>
2163     *
2164     * @param resource the resource to lock
2165     *
2166     * @throws CmsException if something goes wrong
2167     *
2168     * @see CmsObject#lockResource(String)
2169     */
2170    public void lockResourceTemporary(CmsResource resource) throws CmsException {
2171
2172        getResourceType(resource).lockResource(this, m_securityManager, resource, CmsLockType.TEMPORARY);
2173    }
2174
2175    /**
2176     * Locks a resource temporary.<p>
2177     *
2178     * This will be an exclusive, temporary lock valid only for the current users session.
2179     * Usually this should not be used directly, this method is intended for the OpenCms workplace only.<p>
2180     *
2181     * @param resourcename the name of the resource to lock (full current site relative path)
2182     *
2183     * @throws CmsException if something goes wrong
2184     *
2185     * @see CmsObject#lockResource(String)
2186     */
2187    public void lockResourceTemporary(String resourcename) throws CmsException {
2188
2189        lockResource(resourcename, CmsLockType.TEMPORARY);
2190    }
2191
2192    /**
2193     * Logs a user into the Cms, if the password is correct.<p>
2194     *
2195     * @param username the name of the user
2196     * @param password the password of the user
2197     *
2198     * @return the name of the logged in user
2199     *
2200     * @throws CmsException if the login was not successful
2201     */
2202    public String loginUser(String username, String password) throws CmsException {
2203
2204        return loginUser(username, password, m_context.getRemoteAddress());
2205    }
2206
2207    /**
2208     * Logs a user with a given ip address into the Cms, if the password is correct.<p>
2209     *
2210     * @param username the name of the user
2211     * @param password the password of the user
2212     * @param remoteAddress the ip address
2213     *
2214     * @return the name of the logged in user
2215     *
2216     * @throws CmsException if the login was not successful
2217     */
2218    public String loginUser(String username, String password, String remoteAddress) throws CmsException {
2219
2220        // login the user
2221        CmsUser newUser = m_securityManager.loginUser(m_context, username, password, remoteAddress);
2222        // set the project back to the "Online" project
2223        CmsProject newProject = m_securityManager.readProject(CmsProject.ONLINE_PROJECT_ID);
2224        // switch the cms context to the new user and project
2225        m_context.switchUser(newUser, newProject, newUser.getOuFqn());
2226        // init this CmsObject with the new user
2227        init(m_securityManager, m_context);
2228        // fire a login event
2229        fireEvent(I_CmsEventListener.EVENT_LOGIN_USER, newUser);
2230        // return the users login name
2231        return newUser.getName();
2232    }
2233
2234    /**
2235     * Lookups and reads the user or group with the given UUID.<p>
2236     *
2237     * @param principalId the uuid of a user or group
2238     *
2239     * @return the user or group with the given UUID
2240     */
2241    public I_CmsPrincipal lookupPrincipal(CmsUUID principalId) {
2242
2243        return m_securityManager.lookupPrincipal(m_context, principalId);
2244    }
2245
2246    /**
2247     * Lookups and reads the user or group with the given name.<p>
2248     *
2249     * @param principalName the name of the user or group
2250     *
2251     * @return the user or group with the given name
2252     */
2253    public I_CmsPrincipal lookupPrincipal(String principalName) {
2254
2255        return m_securityManager.lookupPrincipal(m_context, principalName);
2256    }
2257
2258    /**
2259     * Moves a resource to the given destination.<p>
2260     *
2261     * A move operation in OpenCms is always a copy (as sibling) followed by a delete,
2262     * this is a result of the online/offline structure of the
2263     * OpenCms VFS. This way you can see the deleted files/folders in the offline
2264     * project, and you will be unable to undelete them.<p>
2265     *
2266     * @param source the name of the resource to move (full current site relative path)
2267     * @param destination the destination resource name (full current site relative path)
2268     *
2269     * @throws CmsException if something goes wrong
2270     *
2271     * @see #renameResource(String, String)
2272     */
2273    public void moveResource(String source, String destination) throws CmsException {
2274
2275        CmsResource resource = readResource(source, CmsResourceFilter.IGNORE_EXPIRATION);
2276        getResourceType(resource).moveResource(this, m_securityManager, resource, destination);
2277    }
2278
2279    /**
2280     * Moves a resource to the "lost and found" folder.<p>
2281     *
2282     * The "lost and found" folder is a special system folder.
2283     *
2284     * This operation is used e.g. during import of resources
2285     * when a resource with the same name but a different resource ID
2286     * already exists in the VFS. In this case, the imported resource is
2287     * moved to the "lost and found" folder.<p>
2288     *
2289     * @param resourcename the name of the resource to move to "lost and found" (full current site relative path)
2290     *
2291     * @return the name of the resource inside the "lost and found" folder
2292     *
2293     * @throws CmsException if something goes wrong
2294     *
2295     * @see #getLostAndFoundName(String)
2296     */
2297    public String moveToLostAndFound(String resourcename) throws CmsException {
2298
2299        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
2300        return m_securityManager.moveToLostAndFound(m_context, resource, false);
2301    }
2302
2303    /**
2304     * Reads all available versions for a given resource.<p>
2305     *
2306     * @param resource the resource for which to read the versions
2307     * @return the list of historical versions of the resource
2308     *
2309     * @throws CmsException if something goes wrong
2310     */
2311    public List<I_CmsHistoryResource> readAllAvailableVersions(CmsResource resource) throws CmsException {
2312
2313        return m_securityManager.readAllAvailableVersions(m_context, resource);
2314    }
2315
2316    /**
2317     * Reads all historical versions of a resource.<br>
2318     *
2319     * The reading excludes the file content, if the resource is a file.<p>
2320     *
2321     * @param resourceName the name of the resource to be read
2322     *
2323     * @return a list of historical resources, as <code>{@link I_CmsHistoryResource}</code> objects
2324     *
2325     * @throws CmsException if operation was not successful
2326     */
2327    public List<I_CmsHistoryResource> readAllAvailableVersions(String resourceName) throws CmsException {
2328
2329        CmsResource resource = readResource(resourceName, CmsResourceFilter.ALL);
2330        return m_securityManager.readAllAvailableVersions(m_context, resource);
2331    }
2332
2333    /**
2334     * Reads all property definitions.<p>
2335     *
2336     * @return a list with the <code>{@link CmsPropertyDefinition}</code> objects (may be empty)
2337     *
2338     * @throws CmsException if something goes wrong
2339     */
2340    public List<CmsPropertyDefinition> readAllPropertyDefinitions() throws CmsException {
2341
2342        return m_securityManager.readAllPropertyDefinitions(m_context);
2343    }
2344
2345    /**
2346     * Returns the first ancestor folder matching the filter criteria.<p>
2347     *
2348     * If no folder matching the filter criteria is found, null is returned.<p>
2349     *
2350     * @param resourcename the name of the resource to start (full current site relative path)
2351     * @param filter the resource filter to match while reading the ancestors
2352     *
2353     * @return the first ancestor folder matching the filter criteria or null if no folder was found
2354     *
2355     * @throws CmsException if something goes wrong
2356     */
2357    public CmsFolder readAncestor(String resourcename, CmsResourceFilter filter) throws CmsException {
2358
2359        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
2360        return m_securityManager.readAncestor(m_context, resource, filter);
2361    }
2362
2363    /**
2364     * Returns the first ancestor folder matching the resource type.<p>
2365     *
2366     * If no folder with the requested resource type is found, null is returned.<p>
2367     *
2368     * @param resourcename the name of the resource to start (full current site relative path)
2369     * @param type the resource type of the folder to match
2370     *
2371     * @return the first ancestor folder matching the filter criteria or null if no folder was found
2372     *
2373     * @throws CmsException if something goes wrong
2374     */
2375    @SuppressWarnings("deprecation")
2376    public CmsFolder readAncestor(String resourcename, int type) throws CmsException {
2377
2378        return readAncestor(resourcename, CmsResourceFilter.requireType(type));
2379    }
2380
2381    /**
2382     * Reads the newest URL name which is mapped to the given structure id.<p>
2383     *
2384     * If the structure id is not mapped to any name, null will be returned.<p>
2385     *
2386     * @param id the structure id for which the newest mapped name should be returned
2387     * @param locale the locale for which the URL name should be selected if possible
2388     * @param defaultLocales the default locales which should be used if the locale is not available
2389     * @return an URL name or null
2390     * @throws CmsException if something goes wrong
2391     */
2392    public String readBestUrlName(CmsUUID id, Locale locale, List<Locale> defaultLocales) throws CmsException {
2393
2394        return m_securityManager.readBestUrlName(m_context, id, locale, defaultLocales);
2395    }
2396
2397    /**
2398     * Returns the default resource for the given folder.<p>
2399     * <ol>
2400     *   <li>the {@link CmsPropertyDefinition#PROPERTY_DEFAULT_FILE} is checked, and
2401     *   <li>if still no file could be found, the configured default files in the
2402     *       <code>opencms-vfs.xml</code> configuration are iterated until a match is
2403     *       found, and
2404     *   <li>if still no file could be found, <code>null</code> is returned
2405     * </ol>
2406     *
2407     * @param folderResource the folder
2408     * @param resourceFilter the resource filter
2409     *
2410     * @return the default file for the given folder
2411     *
2412     * @throws CmsSecurityException  if the user has no permissions to read the resulting file
2413     */
2414    public CmsResource readDefaultFile(CmsResource folderResource, CmsResourceFilter resourceFilter)
2415    throws CmsSecurityException {
2416
2417        return m_securityManager.readDefaultFile(m_context, folderResource, resourceFilter);
2418    }
2419
2420    /**
2421     * Returns the default resource for the given folder.<p>
2422     *
2423     * If the given resource name or id identifies a file, then this file is returned.<p>
2424     *
2425     * Otherwise, in case of a folder:<br>
2426     * <ol>
2427     *   <li>the {@link CmsPropertyDefinition#PROPERTY_DEFAULT_FILE} is checked, and
2428     *   <li>if still no file could be found, the configured default files in the
2429     *       <code>opencms-vfs.xml</code> configuration are iterated until a match is
2430     *       found, and
2431     *   <li>if still no file could be found, <code>null</code> is returned
2432     * </ol>
2433     *
2434     * @param resourceNameOrID the name or id of the folder to read the default file for
2435     *
2436     * @return the default file for the given folder
2437     *
2438     * @throws CmsException if something goes wrong
2439     * @throws CmsSecurityException if the user has no permissions to read the resulting file
2440     */
2441    public CmsResource readDefaultFile(String resourceNameOrID) throws CmsException, CmsSecurityException {
2442
2443        return readDefaultFile(resourceNameOrID, CmsResourceFilter.DEFAULT);
2444    }
2445
2446    /**
2447     * Returns the default resource for the given folder.<p>
2448     *
2449     * If the given resource name or id identifies a file, then this file is returned.<p>
2450     *
2451     * Otherwise, in case of a folder:<br>
2452     * <ol>
2453     *   <li>the {@link CmsPropertyDefinition#PROPERTY_DEFAULT_FILE} is checked, and
2454     *   <li>if still no file could be found, the configured default files in the
2455     *       <code>opencms-vfs.xml</code> configuration are iterated until a match is
2456     *       found, and
2457     *   <li>if still no file could be found, <code>null</code> is returned
2458     * </ol>
2459     *
2460     * @param resourceNameOrID the name or id of the folder to read the default file for#
2461     * @param filter the resource filter to use for reading the resources
2462     *
2463     * @return the default file for the given folder
2464     *
2465     * @throws CmsException if something goes wrong
2466     * @throws CmsSecurityException if the user has no permissions to read the resulting file
2467     */
2468    public CmsResource readDefaultFile(String resourceNameOrID, CmsResourceFilter filter)
2469    throws CmsException, CmsSecurityException {
2470
2471        CmsResource resource;
2472        if (CmsUUID.isValidUUID(resourceNameOrID)) {
2473            resource = readResource(new CmsUUID(resourceNameOrID), filter);
2474        } else {
2475            resource = readResource(resourceNameOrID, filter);
2476        }
2477        return m_securityManager.readDefaultFile(m_context, resource, filter);
2478    }
2479
2480    /**
2481     * Reads all deleted (historical) resources below the given path,
2482     * including the full tree below the path, if required.<p>
2483     *
2484     * The result list may include resources with the same name of
2485     * resources (with different id's).<p>
2486     *
2487     * Use in conjunction with the {@link #restoreDeletedResource(CmsUUID)}
2488     * method.<p>
2489     *
2490     * @param resourcename the parent path to read the resources from
2491     * @param readTree <code>true</code> to read all sub resources
2492     *
2493     * @return a list of <code>{@link I_CmsHistoryResource}</code> objects
2494     *
2495     * @throws CmsException if something goes wrong
2496     *
2497     * @see #readResource(CmsUUID, int)
2498     * @see #readResources(String, CmsResourceFilter, boolean)
2499     */
2500    public List<I_CmsHistoryResource> readDeletedResources(String resourcename, boolean readTree) throws CmsException {
2501
2502        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
2503        return m_securityManager.readDeletedResources(m_context, resource, readTree);
2504    }
2505
2506    /**
2507     * Reads a file resource (including it's binary content) from the VFS,
2508     * for the given resource (this may also be an historical version of the resource).<p>
2509     *
2510     * In case the input {@link CmsResource} object already is a {@link CmsFile} with contents
2511     * available, it is casted to a file and returned unchanged. Otherwise the file is read
2512     * from the VFS.<p>
2513     *
2514     * In case you do not need the file content,
2515     * use <code>{@link #readResource(String)}</code> or
2516     * <code>{@link #readResource(String, CmsResourceFilter)}</code> instead.<p>
2517     *
2518     * No resource filter is applied when reading the resource, since we already have
2519     * a full resource instance and assume we just want the content for that instance.
2520     * In case you need to apply a filter, use {@link #readFile(String, CmsResourceFilter)} instead.<p>
2521     *
2522     * @param resource the resource to read
2523     *
2524     * @return the file resource that was read
2525     *
2526     * @throws CmsException if the file resource could not be read for any reason
2527     *
2528     * @see #readFile(String)
2529     * @see #readFile(String, CmsResourceFilter)
2530     */
2531    public CmsFile readFile(CmsResource resource) throws CmsException {
2532
2533        // test if we already have a file
2534        if (resource instanceof CmsFile) {
2535            // resource is already a file
2536            CmsFile file = (CmsFile)resource;
2537            if ((file.getContents() != null) && (file.getContents().length > 0)) {
2538                // file has the contents already available
2539                return file;
2540            }
2541        }
2542
2543        return m_securityManager.readFile(m_context, resource);
2544    }
2545
2546    /**
2547     * Reads a file resource (including it's binary content) from the VFS,
2548     * using the <code>{@link CmsResourceFilter#DEFAULT}</code> filter.<p>
2549     *
2550     * In case you do not need the file content,
2551     * use <code>{@link #readResource(String)}</code> instead.<p>
2552     *
2553     * @param resourcename the name of the resource to read (full current site relative path)
2554     *
2555     * @return the file resource that was read
2556     *
2557     * @throws CmsException if the file resource could not be read for any reason
2558     *
2559     * @see #readFile(String, CmsResourceFilter)
2560     * @see #readFile(CmsResource)
2561     * @see #readResource(String)
2562     */
2563    public CmsFile readFile(String resourcename) throws CmsException {
2564
2565        return readFile(resourcename, CmsResourceFilter.DEFAULT);
2566    }
2567
2568    /**
2569     * Reads a file resource (including it's binary content) from the VFS,
2570     * using the specified resource filter.<p>
2571     *
2572     * In case you do not need the file content,
2573     * use <code>{@link #readResource(String, CmsResourceFilter)}</code> instead.<p>
2574     *
2575     * The specified filter controls what kind of resources should be "found"
2576     * during the read operation. This will depend on the application. For example,
2577     * using <code>{@link CmsResourceFilter#DEFAULT}</code> will only return currently
2578     * "valid" resources, while using <code>{@link CmsResourceFilter#IGNORE_EXPIRATION}</code>
2579     * will ignore the date release / date expired information of the resource.<p>
2580     *
2581     * @param resourcename the name of the resource to read (full current site relative path)
2582     * @param filter the resource filter to use while reading
2583     *
2584     * @return the file resource that was read
2585     *
2586     * @throws CmsException if the file resource could not be read for any reason
2587     *
2588     * @see #readFile(String)
2589     * @see #readFile(CmsResource)
2590     * @see #readResource(String, CmsResourceFilter)
2591     */
2592    public CmsFile readFile(String resourcename, CmsResourceFilter filter) throws CmsException {
2593
2594        CmsResource resource = readResource(resourcename, filter);
2595        return readFile(resource);
2596    }
2597
2598    /**
2599     * Reads a folder resource from the VFS,
2600     * using the <code>{@link CmsResourceFilter#DEFAULT}</code> filter.<p>
2601     *
2602     * @param resourcename the name of the folder resource to read (full current site relative path)
2603     *
2604     * @return the folder resource that was read
2605     *
2606     * @throws CmsException if the resource could not be read for any reason
2607     *
2608     * @see #readResource(String, CmsResourceFilter)
2609     * @see #readFolder(String, CmsResourceFilter)
2610     */
2611    public CmsFolder readFolder(String resourcename) throws CmsException {
2612
2613        return readFolder(resourcename, CmsResourceFilter.DEFAULT);
2614    }
2615
2616    /**
2617     * Reads a folder resource from the VFS,
2618     * using the specified resource filter.<p>
2619     *
2620     * The specified filter controls what kind of resources should be "found"
2621     * during the read operation. This will depend on the application. For example,
2622     * using <code>{@link CmsResourceFilter#DEFAULT}</code> will only return currently
2623     * "valid" resources, while using <code>{@link CmsResourceFilter#IGNORE_EXPIRATION}</code>
2624     * will ignore the date release / date expired information of the resource.<p>
2625     *
2626     * @param resourcename the name of the folder resource to read (full current site relative path)
2627     * @param filter the resource filter to use while reading
2628     *
2629     * @return the folder resource that was read
2630     *
2631     * @throws CmsException if the resource could not be read for any reason
2632     *
2633     * @see #readResource(String, CmsResourceFilter)
2634     */
2635    public CmsFolder readFolder(String resourcename, CmsResourceFilter filter) throws CmsException {
2636
2637        return m_securityManager.readFolder(m_context, addSiteRoot(resourcename), filter);
2638    }
2639
2640    /**
2641     * Reads the group of a project.<p>
2642     *
2643     * @param project the project to read the group from
2644     *
2645     * @return the group of the given project
2646     */
2647    public CmsGroup readGroup(CmsProject project) {
2648
2649        return m_securityManager.readGroup(m_context, project);
2650    }
2651
2652    /**
2653     * Reads a group based on its id.<p>
2654     *
2655     * @param groupId the id of the group to be read
2656     *
2657     * @return the group that has the provided id
2658     *
2659     * @throws CmsException if something goes wrong
2660     *
2661     * @see #readHistoryPrincipal(CmsUUID) for retrieving deleted groups
2662     */
2663    public CmsGroup readGroup(CmsUUID groupId) throws CmsException {
2664
2665        return m_securityManager.readGroup(m_context, groupId);
2666    }
2667
2668    /**
2669     * Reads a group based on its name.<p>
2670     *
2671     * @param groupName the name of the group to be read
2672     *
2673     * @return the group that has the provided name
2674     *
2675     * @throws CmsException if something goes wrong
2676     */
2677    public CmsGroup readGroup(String groupName) throws CmsException {
2678
2679        return m_securityManager.readGroup(m_context, groupName);
2680    }
2681
2682    /**
2683     * Reads a principal (an user or group) from the historical archive based on its ID.<p>
2684     *
2685     * @param principalId the id of the principal to read
2686     *
2687     * @return the historical principal entry with the given id
2688     *
2689     * @throws CmsException if something goes wrong, ie. {@link org.opencms.db.CmsDbEntryNotFoundException}
2690     *
2691     * @see #readUser(CmsUUID)
2692     * @see #readGroup(CmsUUID)
2693     */
2694    public CmsHistoryPrincipal readHistoryPrincipal(CmsUUID principalId) throws CmsException {
2695
2696        return m_securityManager.readHistoricalPrincipal(m_context, principalId);
2697    }
2698
2699    /**
2700     * Returns the latest historical project entry with the given id.<p>
2701     *
2702     * @param projectId the project id
2703     *
2704     * @return the requested historical project entry
2705     *
2706     * @throws CmsException if operation was not successful
2707     */
2708    public CmsHistoryProject readHistoryProject(CmsUUID projectId) throws CmsException {
2709
2710        return (m_securityManager.readHistoryProject(m_context, projectId));
2711    }
2712
2713    /**
2714     * Returns a historical project entry.<p>
2715     *
2716     * @param publishTag publish tag of the project
2717     *
2718     * @return the requested historical project entry
2719     *
2720     * @throws CmsException if operation was not successful
2721     */
2722    public CmsHistoryProject readHistoryProject(int publishTag) throws CmsException {
2723
2724        return (m_securityManager.readHistoryProject(m_context, publishTag));
2725    }
2726
2727    /**
2728     * Reads the list of all <code>{@link CmsProperty}</code> objects that belong to the given historical resource version.<p>
2729     *
2730     * @param resource the historical resource version to read the properties for
2731     *
2732     * @return the list of <code>{@link CmsProperty}</code> objects
2733     *
2734     * @throws CmsException if something goes wrong
2735     */
2736    public List<CmsProperty> readHistoryPropertyObjects(I_CmsHistoryResource resource) throws CmsException {
2737
2738        return m_securityManager.readHistoryPropertyObjects(m_context, resource);
2739    }
2740
2741    /**
2742     * This method retrieves the structure id which is mapped to a given URL name.<p>
2743     *
2744     * If there is no structure id mapped to the given name, null will be returned.<p>
2745     *
2746     * However if the parameter is a string which represents a valid uuid, it will be directly returned as a {@link CmsUUID} instance.<p>
2747     *
2748     * @param name the url name
2749     * @return the id which is mapped to the URL name
2750     *
2751     * @throws CmsException if something goes wrong
2752     */
2753    public CmsUUID readIdForUrlName(String name) throws CmsException {
2754
2755        if (CmsUUID.isValidUUID(name)) {
2756            return new CmsUUID(name);
2757        }
2758        return m_securityManager.readIdForUrlName(m_context, name);
2759    }
2760
2761    /**
2762     * Returns the project manager group of a project.<p>
2763     *
2764     * @param project the project
2765     *
2766     * @return the manager group of the project
2767     */
2768    public CmsGroup readManagerGroup(CmsProject project) {
2769
2770        return m_securityManager.readManagerGroup(m_context, project);
2771    }
2772
2773    /**
2774     * Reads the owner of a project.<p>
2775     *
2776     * @param project the project to read the owner from
2777     *
2778     * @return the owner of the project
2779     *
2780     * @throws CmsException if something goes wrong
2781     */
2782    public CmsUser readOwner(CmsProject project) throws CmsException {
2783
2784        return m_securityManager.readOwner(m_context, project);
2785    }
2786
2787    /**
2788     * Returns the parent folder to the given structure id.<p>
2789     *
2790     * @param structureId the child structure id
2791     *
2792     * @return the parent folder <code>{@link CmsResource}</code>
2793     *
2794     * @throws CmsException if something goes wrong
2795     */
2796    public CmsResource readParentFolder(CmsUUID structureId) throws CmsException {
2797
2798        return m_securityManager.readParentFolder(m_context, structureId);
2799    }
2800
2801    /**
2802     * Builds a list of resources for a given path.<p>
2803     *
2804     * @param resource the resource to read the path for
2805     * @param filter a filter object (only "includeDeleted" information is used!)
2806     *
2807     * @return list of <code>{@link CmsResource}</code>s
2808     *
2809     * @throws CmsException if something goes wrong
2810     */
2811    public List<CmsResource> readPath(CmsResource resource, CmsResourceFilter filter) throws CmsException {
2812
2813        return m_securityManager.readPath(m_context, resource.getRootPath(), filter);
2814    }
2815
2816    /**
2817     * Builds a list of resources for a given path.<p>
2818     *
2819     * @param path the requested path
2820     * @param filter a filter object (only "includeDeleted" information is used!)
2821     *
2822     * @return list of <code>{@link CmsResource}</code>s
2823     *
2824     * @throws CmsException if something goes wrong
2825     */
2826    public List<CmsResource> readPath(String path, CmsResourceFilter filter) throws CmsException {
2827
2828        return m_securityManager.readPath(m_context, addSiteRoot(path), filter);
2829    }
2830
2831    /**
2832     * Reads the project with the given id.<p>
2833     *
2834     * @param id the id of the project
2835     *
2836     * @return the project with the given id
2837     *
2838     * @throws CmsException if operation was not successful
2839     */
2840    public CmsProject readProject(CmsUUID id) throws CmsException {
2841
2842        return m_securityManager.readProject(id);
2843    }
2844
2845    /**
2846     * Reads the project with the given name.<p>
2847     *
2848     * @param name the name of the project
2849     *
2850     * @return the project with the given name
2851     *
2852     * @throws CmsException if operation was not successful
2853     */
2854    public CmsProject readProject(String name) throws CmsException {
2855
2856        return m_securityManager.readProject(name);
2857    }
2858
2859    /**
2860     * Returns the list of all resource names that define the "view" of the given project.<p>
2861     *
2862     * @param project the project to get the project resources for
2863     *
2864     * @return the list of all resource names (root paths), as <code>{@link String}</code>
2865     *              objects that define the "view" of the given project
2866     *
2867     * @throws CmsException if something goes wrong
2868     */
2869    public List<String> readProjectResources(CmsProject project) throws CmsException {
2870
2871        return m_securityManager.readProjectResources(m_context, project);
2872    }
2873
2874    /**
2875     * Reads all resources of a project that match a given state from the VFS.<p>
2876     *
2877     * Possible values for the <code>state</code> parameter are:<br>
2878     * <ul>
2879     * <li><code>{@link CmsResource#STATE_CHANGED}</code>: Read all "changed" resources in the project</li>
2880     * <li><code>{@link CmsResource#STATE_NEW}</code>: Read all "new" resources in the project</li>
2881     * <li><code>{@link CmsResource#STATE_DELETED}</code>: Read all "deleted" resources in the project</li>
2882     * <li><code>{@link CmsResource#STATE_KEEP}</code>: Read all resources either "changed", "new" or "deleted" in the project</li>
2883     * </ul><p>
2884     *
2885     * @param projectId the id of the project to read the file resources for
2886     * @param state the resource state to match
2887     *
2888     * @return all <code>{@link CmsResource}</code>s of a project that match a given criteria from the VFS
2889     *
2890     * @throws CmsException if something goes wrong
2891     */
2892    public List<CmsResource> readProjectView(CmsUUID projectId, CmsResourceState state) throws CmsException {
2893
2894        return m_securityManager.readProjectView(m_context, projectId, state);
2895    }
2896
2897    /**
2898     * Reads a property definition.<p>
2899     *
2900     * If no property definition with the given name is found,
2901     * <code>null</code> is returned.<p>
2902     *
2903     * @param name the name of the property definition to read
2904     *
2905     * @return the property definition that was read
2906     *
2907     * @throws CmsException a CmsDbEntryNotFoundException is thrown if the property definition does not exist
2908     */
2909    public CmsPropertyDefinition readPropertyDefinition(String name) throws CmsException {
2910
2911        return (m_securityManager.readPropertyDefinition(m_context, name));
2912    }
2913
2914    /**
2915     * Reads a property object from a resource specified by a property name.<p>
2916     *
2917     * Returns <code>{@link CmsProperty#getNullProperty()}</code> if the property is not found.<p>
2918     *
2919     * This method is more efficient then using <code>{@link CmsObject#readPropertyObject(String, String, boolean)}</code>
2920     * if you already have an instance of the resource to look up the property from.<p>
2921     *
2922     * @param resource the resource where the property is attached to
2923     * @param property the property name
2924     * @param search if true, the property is searched on all parent folders of the resource,
2925     *      if it's not found attached directly to the resource
2926     *
2927     * @return the required property, or <code>{@link CmsProperty#getNullProperty()}</code> if the property was not found
2928     *
2929     * @throws CmsException if something goes wrong
2930     */
2931    public CmsProperty readPropertyObject(CmsResource resource, String property, boolean search) throws CmsException {
2932
2933        return m_securityManager.readPropertyObject(m_context, resource, property, search);
2934    }
2935
2936    /**
2937     * Reads the locale specific version of a property object from a resource specified by a property name.<p>
2938     *
2939     * Returns <code>{@link CmsProperty#getNullProperty()}</code> if the property is not found.<p>
2940     *
2941     * This method is more efficient then using <code>{@link CmsObject#readPropertyObject(String, String, boolean)}</code>
2942     * if you already have an instance of the resource to look up the property from.<p>
2943     *
2944     * @param resource the resource where the property is attached to
2945     * @param property the property name
2946     * @param search if true, the property is searched on all parent folders of the resource,
2947     *      if it's not found attached directly to the resource
2948     * @param locale the locale for which the property should be read.
2949     *
2950     * @return the required property, or <code>{@link CmsProperty#getNullProperty()}</code> if the property was not found
2951     *
2952     * @throws CmsException if something goes wrong
2953     */
2954    public CmsProperty readPropertyObject(CmsResource resource, String property, boolean search, Locale locale)
2955    throws CmsException {
2956
2957        return m_securityManager.readPropertyObject(m_context, resource, property, search, locale);
2958    }
2959
2960    /**
2961     * Reads a property object from a resource specified by a property name.<p>
2962     *
2963     * Returns <code>{@link CmsProperty#getNullProperty()}</code> if the property is not found.<p>
2964     *
2965     * @param resourcePath the name of resource where the property is attached to
2966     * @param property the property name
2967     * @param search if true, the property is searched on all parent folders of the resource,
2968     *      if it's not found attached directly to the resource
2969     *
2970     * @return the required property, or <code>{@link CmsProperty#getNullProperty()}</code> if the property was not found
2971     *
2972     * @throws CmsException if something goes wrong
2973     */
2974    public CmsProperty readPropertyObject(String resourcePath, String property, boolean search) throws CmsException {
2975
2976        CmsResource resource = readResource(resourcePath, CmsResourceFilter.ALL);
2977        return m_securityManager.readPropertyObject(m_context, resource, property, search);
2978    }
2979
2980    /**
2981     * Reads the locale specific version of a property object from a resource specified by a property name.<p>
2982     *
2983     * Returns <code>{@link CmsProperty#getNullProperty()}</code> if the property is not found.<p>
2984     *
2985     * @param resourcePath the name of resource where the property is attached to
2986     * @param property the property name
2987     * @param search if true, the property is searched on all parent folders of the resource,
2988     *      if it's not found attached directly to the resource
2989     * @param locale the locale for which the property should be read.
2990     *
2991     * @return the required property, or <code>{@link CmsProperty#getNullProperty()}</code> if the property was not found
2992     *
2993     * @throws CmsException if something goes wrong
2994     */
2995    public CmsProperty readPropertyObject(String resourcePath, String property, boolean search, Locale locale)
2996    throws CmsException {
2997
2998        CmsResource resource = readResource(resourcePath, CmsResourceFilter.ALL);
2999        return m_securityManager.readPropertyObject(m_context, resource, property, search, locale);
3000    }
3001
3002    /**
3003     * Reads all property objects from a resource.<p>
3004     *
3005     * Returns an empty list if no properties are found.<p>
3006     *
3007     * This method is more efficient then using <code>{@link CmsObject#readPropertyObjects(String, boolean)}</code>
3008     * if you already have an instance of the resource to look up the property from.<p>
3009     *
3010     * If the <code>search</code> parameter is <code>true</code>, the properties of all
3011     * parent folders of the resource are also read. The results are merged with the
3012     * properties directly attached to the resource. While merging, a property
3013     * on a parent folder that has already been found will be ignored.
3014     * So e.g. if a resource has a property "Title" attached, and it's parent folder
3015     * has the same property attached but with a different value, the result list will
3016     * contain only the property with the value from the resource, not form the parent folder(s).<p>
3017     *
3018     * @param resource the resource where the property is mapped to
3019     * @param search if <code>true</code>, the properties of all parent folders of the resource
3020     *      are merged with the resource properties.
3021     *
3022     * @return a list of <code>{@link CmsProperty}</code> objects
3023     *
3024     * @throws CmsException if something goes wrong
3025     */
3026    public List<CmsProperty> readPropertyObjects(CmsResource resource, boolean search) throws CmsException {
3027
3028        return m_securityManager.readPropertyObjects(m_context, resource, search);
3029    }
3030
3031    /**
3032     * Reads all property objects from a resource.<p>
3033     *
3034     * Returns an empty list if no properties are found.<p>
3035     *
3036     * All properties in the result List will be in frozen (read only) state, so you can't change the values.<p>
3037     *
3038     * If the <code>search</code> parameter is <code>true</code>, the properties of all
3039     * parent folders of the resource are also read. The results are merged with the
3040     * properties directly attached to the resource. While merging, a property
3041     * on a parent folder that has already been found will be ignored.
3042     * So e.g. if a resource has a property "Title" attached, and it's parent folder
3043     * has the same property attached but with a different value, the result list will
3044     * contain only the property with the value from the resource, not form the parent folder(s).<p>
3045     *
3046     * @param resourcePath the name of resource where the property is mapped to
3047     * @param search if <code>true</code>, the properties of all parent folders of the resource
3048     *      are merged with the resource properties.
3049     *
3050     * @return a list of <code>{@link CmsProperty}</code> objects
3051     *
3052     * @throws CmsException if something goes wrong
3053     */
3054    public List<CmsProperty> readPropertyObjects(String resourcePath, boolean search) throws CmsException {
3055
3056        CmsResource resource = readResource(resourcePath, CmsResourceFilter.ALL);
3057        return m_securityManager.readPropertyObjects(m_context, resource, search);
3058    }
3059
3060    /**
3061     * Reads the resources that were published in a publish task for a given publish history ID.<p>
3062     *
3063     * @param publishHistoryId unique ID to identify each publish task in the publish history
3064     *
3065     * @return a list of <code>{@link org.opencms.db.CmsPublishedResource}</code> objects
3066     *
3067     * @throws CmsException if something goes wrong
3068     */
3069    public List<CmsPublishedResource> readPublishedResources(CmsUUID publishHistoryId) throws CmsException {
3070
3071        return m_securityManager.readPublishedResources(m_context, publishHistoryId);
3072    }
3073
3074    /**
3075     * Returns all relations matching the given filter.<p>
3076     *
3077     * @param filter the filter to match the relation
3078     *
3079     * @return all relations matching the given filter
3080     *
3081     * @throws CmsException if something goes wrong
3082     *
3083     * @see CmsSecurityManager#getRelationsForResource(CmsRequestContext, CmsResource, CmsRelationFilter)
3084     * @see #getRelationsForResource(CmsResource, CmsRelationFilter)
3085     */
3086    public List<CmsRelation> readRelations(CmsRelationFilter filter) throws CmsException {
3087
3088        return m_securityManager.getRelationsForResource(m_context, null, filter);
3089    }
3090
3091    /**
3092     * Reads a resource from the VFS,
3093     * using the <code>{@link CmsResourceFilter#DEFAULT}</code> filter.<p>
3094     *
3095     * A resource may be of type <code>{@link CmsFile}</code> or
3096     * <code>{@link CmsFolder}</code>. In case of
3097     * a file, the resource will not contain the binary file content. Since reading
3098     * the binary content is a cost-expensive database operation, it's recommended
3099     * to work with resources if possible, and only read the file content when absolutely
3100     * required. To "upgrade" a resource to a file,
3101     * use <code>{@link #readFile(CmsResource)}</code>.<p>
3102     *
3103     * @param structureID the structure ID of the resource to read
3104     *
3105     * @return the resource that was read
3106     *
3107     * @throws CmsException if the resource could not be read for any reason
3108     *
3109     * @see #readFile(String)
3110     * @see #readResource(CmsUUID, CmsResourceFilter)
3111     */
3112    public CmsResource readResource(CmsUUID structureID) throws CmsException {
3113
3114        return readResource(structureID, CmsResourceFilter.DEFAULT);
3115    }
3116
3117    /**
3118     * Reads a resource from the VFS,
3119     * using the specified resource filter.<p>
3120     *
3121     * A resource may be of type <code>{@link CmsFile}</code> or
3122     * <code>{@link CmsFolder}</code>. In case of
3123     * a file, the resource will not contain the binary file content. Since reading
3124     * the binary content is a cost-expensive database operation, it's recommended
3125     * to work with resources if possible, and only read the file content when absolutely
3126     * required. To "upgrade" a resource to a file,
3127     * use <code>{@link #readFile(CmsResource)}</code>.<p>
3128     *
3129     * The specified filter controls what kind of resources should be "found"
3130     * during the read operation. This will depend on the application. For example,
3131     * using <code>{@link CmsResourceFilter#DEFAULT}</code> will only return currently
3132     * "valid" resources, while using <code>{@link CmsResourceFilter#IGNORE_EXPIRATION}</code>
3133     * will ignore the date release / date expired information of the resource.<p>
3134     *
3135     * @param structureID the structure ID of the resource to read
3136     * @param filter the resource filter to use while reading
3137     *
3138     * @return the resource that was read
3139     *
3140     * @throws CmsException if the resource could not be read for any reason
3141     *
3142     * @see #readFile(String, CmsResourceFilter)
3143     * @see #readFolder(String, CmsResourceFilter)
3144     */
3145    public CmsResource readResource(CmsUUID structureID, CmsResourceFilter filter) throws CmsException {
3146
3147        return m_securityManager.readResource(m_context, structureID, filter);
3148    }
3149
3150    /**
3151     * Reads the historical resource with the given version for the resource given
3152     * the given structure id.<p>
3153     *
3154     * A resource may be of type <code>{@link CmsFile}</code> or
3155     * <code>{@link CmsFolder}</code>. In case of a file, the resource will not
3156     * contain the binary file content. Since reading the binary content is a
3157     * cost-expensive database operation, it's recommended to work with resources
3158     * if possible, and only read the file content when absolutely required. To
3159     * "upgrade" a resource to a file, use
3160     * <code>{@link #readFile(CmsResource)}</code>.<p>
3161     *
3162     * Please note that historical versions are just generated during publishing,
3163     * so the first version with version number 1 is generated during publishing
3164     * of a new resource (exception is a new sibling, that may also contain some
3165     * relevant versions of already published siblings) and the last version
3166     * available is the version of the current online resource.<p>
3167     *
3168     * @param structureID the structure ID of the resource to read
3169     * @param version the version number you want to retrieve
3170     *
3171     * @return the resource that was read
3172     *
3173     * @throws CmsException if the resource could not be read for any reason
3174     * @throws CmsVfsResourceNotFoundException if the version does not exists
3175     *
3176     * @see #restoreResourceVersion(CmsUUID, int)
3177     */
3178    public I_CmsHistoryResource readResource(CmsUUID structureID, int version)
3179    throws CmsException, CmsVfsResourceNotFoundException {
3180
3181        CmsResource resource = readResource(structureID, CmsResourceFilter.ALL);
3182        return m_securityManager.readResource(m_context, resource, version);
3183    }
3184
3185    /**
3186     * Reads a resource from the VFS,
3187     * using the <code>{@link CmsResourceFilter#DEFAULT}</code> filter.<p>
3188     *
3189     * A resource may be of type <code>{@link CmsFile}</code> or
3190     * <code>{@link CmsFolder}</code>. In case of
3191     * a file, the resource will not contain the binary file content. Since reading
3192     * the binary content is a cost-expensive database operation, it's recommended
3193     * to work with resources if possible, and only read the file content when absolutely
3194     * required. To "upgrade" a resource to a file,
3195     * use <code>{@link #readFile(CmsResource)}</code>.<p>
3196     *
3197     * @param resourcename the name of the resource to read (full current site relative path)
3198     *
3199     * @return the resource that was read
3200     *
3201     * @throws CmsException if the resource could not be read for any reason
3202     *
3203     * @see #readFile(String)
3204     * @see #readResource(String, CmsResourceFilter)
3205     */
3206    public CmsResource readResource(String resourcename) throws CmsException {
3207
3208        return readResource(resourcename, CmsResourceFilter.DEFAULT);
3209    }
3210
3211    /**
3212     * Reads a resource from the VFS,
3213     * using the specified resource filter.<p>
3214     *
3215     * A resource may be of type <code>{@link CmsFile}</code> or
3216     * <code>{@link CmsFolder}</code>. In case of
3217     * a file, the resource will not contain the binary file content. Since reading
3218     * the binary content is a cost-expensive database operation, it's recommended
3219     * to work with resources if possible, and only read the file content when absolutely
3220     * required. To "upgrade" a resource to a file,
3221     * use <code>{@link #readFile(CmsResource)}</code>.<p>
3222     *
3223     * The specified filter controls what kind of resources should be "found"
3224     * during the read operation. This will depend on the application. For example,
3225     * using <code>{@link CmsResourceFilter#DEFAULT}</code> will only return currently
3226     * "valid" resources, while using <code>{@link CmsResourceFilter#IGNORE_EXPIRATION}</code>
3227     * will ignore the date release / date expired information of the resource.<p>
3228     *
3229     * @param resourcename the name of the resource to read (full current site relative path)
3230     * @param filter the resource filter to use while reading
3231     *
3232     * @return the resource that was read
3233     *
3234     * @throws CmsException if the resource could not be read for any reason
3235     *
3236     * @see #readFile(String, CmsResourceFilter)
3237     * @see #readFolder(String, CmsResourceFilter)
3238     */
3239    public CmsResource readResource(String resourcename, CmsResourceFilter filter) throws CmsException {
3240
3241        return m_securityManager.readResource(m_context, addSiteRoot(resourcename), filter);
3242    }
3243
3244    /**
3245     * Reads all resources below the given resource matching the filter criteria,
3246     * including the full tree below the path only in case the <code>readTree</code>
3247     * parameter is <code>true</code>.<p>
3248     *
3249     * @param resource the parent resource
3250     * @param filter the filter
3251     * @param readTree <code>true</code> to read all sub resources
3252     *
3253     * @return a list of <code>{@link CmsResource}</code> objects matching the filter criteria
3254     *
3255     * @throws CmsException if something goes wrong
3256     */
3257    public List<CmsResource> readResources(CmsResource resource, CmsResourceFilter filter, boolean readTree)
3258    throws CmsException {
3259
3260        if (readTree) {
3261            return m_securityManager.readResources(m_context, resource, filter, readTree);
3262        } else {
3263            return m_securityManager.readChildResources(m_context, resource, filter, true, true);
3264        }
3265    }
3266
3267    /**
3268     * Reads all resources below the given path matching the filter criteria,
3269     * including the full tree below the path.<p>
3270     *
3271     * @param resourcename the parent path to read the resources from
3272     * @param filter the filter
3273     *
3274     * @return a list of <code>{@link CmsResource}</code> objects matching the filter criteria
3275     *
3276     * @throws CmsException if something goes wrong
3277     *
3278     * @see #readResources(String, CmsResourceFilter, boolean)
3279     */
3280    public List<CmsResource> readResources(String resourcename, CmsResourceFilter filter) throws CmsException {
3281
3282        return readResources(resourcename, filter, true);
3283    }
3284
3285    /**
3286     * Reads all resources below the given path matching the filter criteria,
3287     * including the full tree below the path only in case the <code>readTree</code>
3288     * parameter is <code>true</code>.<p>
3289     *
3290     * @param resourcename the parent path to read the resources from
3291     * @param filter the filter
3292     * @param readTree <code>true</code> to read all sub resources
3293     *
3294     * @return a list of <code>{@link CmsResource}</code> objects matching the filter criteria
3295     *
3296     * @throws CmsException if something goes wrong
3297     */
3298    public List<CmsResource> readResources(String resourcename, CmsResourceFilter filter, boolean readTree)
3299    throws CmsException {
3300
3301        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
3302        return m_securityManager.readResources(m_context, resource, filter, readTree);
3303    }
3304
3305    /**
3306     * Reads all resources that have a value set for the specified property.<p>
3307     *
3308     * Both individual and shared properties of a resource are checked.<p>
3309     *
3310     * Will use the {@link CmsResourceFilter#ALL} resource filter.<p>
3311     *
3312     * @param propertyDefinition the name of the property to check for
3313     *
3314     * @return a list of all <code>{@link CmsResource}</code> objects
3315     *          that have a value set for the specified property.
3316     *
3317     * @throws CmsException if something goes wrong
3318     */
3319    public List<CmsResource> readResourcesWithProperty(String propertyDefinition) throws CmsException {
3320
3321        return readResourcesWithProperty("/", propertyDefinition);
3322    }
3323
3324    /**
3325     * Reads all resources that have a value set for the specified property in the given path.<p>
3326     *
3327     * Both individual and shared properties of a resource are checked.<p>
3328     *
3329     * Will use the {@link CmsResourceFilter#ALL} resource filter.<p>
3330     *
3331     * @param path the folder to get the resources with the property from
3332     * @param propertyDefinition the name of the property to check for
3333     *
3334     * @return all <code>{@link CmsResource}</code> objects
3335     *          that have a value set for the specified property in the given path.
3336     *
3337     * @throws CmsException if something goes wrong
3338     */
3339    public List<CmsResource> readResourcesWithProperty(String path, String propertyDefinition) throws CmsException {
3340
3341        return readResourcesWithProperty(path, propertyDefinition, null);
3342    }
3343
3344    /**
3345     * Reads all resources that have a value (containing the specified value) set
3346     * for the specified property in the given path.<p>
3347     *
3348     * Both individual and shared properties of a resource are checked.<p>
3349     *
3350     * If the <code>value</code> parameter is <code>null</code>, all resources having the
3351     * given property set are returned.<p>
3352     *
3353     * Will use the {@link CmsResourceFilter#ALL} resource filter.<p>
3354     *
3355     * @param path the folder to get the resources with the property from
3356     * @param propertyDefinition the name of the property to check for
3357     * @param value the string to search in the value of the property
3358     *
3359     * @return all <code>{@link CmsResource}</code> objects
3360     *          that have a value set for the specified property in the given path.
3361     *
3362     * @throws CmsException if something goes wrong
3363     */
3364    public List<CmsResource> readResourcesWithProperty(String path, String propertyDefinition, String value)
3365    throws CmsException {
3366
3367        CmsResource resource = readResource(path, CmsResourceFilter.IGNORE_EXPIRATION);
3368        return m_securityManager.readResourcesWithProperty(
3369            m_context,
3370            resource,
3371            propertyDefinition,
3372            value,
3373            CmsResourceFilter.ALL);
3374    }
3375
3376    /**
3377     * Reads all resources that have a value (containing the specified value) set
3378     * for the specified property in the given path.<p>
3379     *
3380     * Both individual and shared properties of a resource are checked.<p>
3381     *
3382     * If the <code>value</code> parameter is <code>null</code>, all resources having the
3383     * given property set are returned.<p>
3384     *
3385     * Will use the given resource filter.<p>
3386     *
3387     * @param path the folder to get the resources with the property from
3388     * @param propertyDefinition the name of the property to check for
3389     * @param value the string to search in the value of the property
3390     * @param filter the resource filter to apply to the result set
3391     *
3392     * @return all <code>{@link CmsResource}</code> objects
3393     *          that have a value set for the specified property in the given path.
3394     *
3395     * @throws CmsException if something goes wrong
3396     */
3397    public List<CmsResource> readResourcesWithProperty(
3398        String path,
3399        String propertyDefinition,
3400        String value,
3401        CmsResourceFilter filter)
3402    throws CmsException {
3403
3404        CmsResource resource = readResource(path, CmsResourceFilter.IGNORE_EXPIRATION);
3405        return m_securityManager.readResourcesWithProperty(m_context, resource, propertyDefinition, value, filter);
3406    }
3407
3408    /**
3409     * Returns a set of principals that are responsible for a specific resource.<p>
3410     *
3411     * @param resource the resource to get the responsible principals from
3412     *
3413     * @return the set of principals that are responsible for a specific resource
3414     *
3415     * @throws CmsException if something goes wrong
3416     */
3417    public Set<I_CmsPrincipal> readResponsiblePrincipals(CmsResource resource) throws CmsException {
3418
3419        return m_securityManager.readResponsiblePrincipals(m_context, resource);
3420    }
3421
3422    /**
3423     * Returns a set of users that are responsible for a specific resource.<p>
3424     *
3425     * @param resource the resource to get the responsible users from
3426     *
3427     * @return the set of users that are responsible for a specific resource
3428     *
3429     * @throws CmsException if something goes wrong
3430     */
3431    public Set<CmsUser> readResponsibleUsers(CmsResource resource) throws CmsException {
3432
3433        return m_securityManager.readResponsibleUsers(m_context, resource);
3434    }
3435
3436    /**
3437     * Returns a list of all siblings of the specified resource,
3438     * the specified resource being always part of the result set.<p>
3439     *
3440     * @param resource the resource
3441     * @param filter a resource filter
3442     *
3443     * @return a list of <code>{@link CmsResource}</code>s that
3444     *          are siblings to the specified resource,
3445     *          including the specified resource itself.
3446     *
3447     * @throws CmsException if something goes wrong
3448     */
3449    public List<CmsResource> readSiblings(CmsResource resource, CmsResourceFilter filter) throws CmsException {
3450
3451        return m_securityManager.readSiblings(m_context, resource, filter);
3452    }
3453
3454    /**
3455     * Returns a list of all siblings of the specified resource,
3456     * the specified resource being always part of the result set.<p>
3457     *
3458     * @param resourcename the name of the specified resource
3459     * @param filter a resource filter
3460     *
3461     * @return a list of <code>{@link CmsResource}</code>s that
3462     *          are siblings to the specified resource,
3463     *          including the specified resource itself.
3464     *
3465     * @throws CmsException if something goes wrong
3466     */
3467    public List<CmsResource> readSiblings(String resourcename, CmsResourceFilter filter) throws CmsException {
3468
3469        CmsResource resource = readResource(resourcename, filter);
3470        return readSiblings(resource, filter);
3471    }
3472
3473    /**
3474     * Reads all resources with the given resource id.<p>
3475     *
3476     * @param resourceId the resource id for which we want the siblings
3477     * @param filter the resource filter used to read the resources
3478     * @return the siblings which share the given resource id
3479     *
3480     * @throws CmsException if something goes wrong
3481     */
3482    public List<CmsResource> readSiblingsForResourceId(CmsUUID resourceId, CmsResourceFilter filter)
3483    throws CmsException {
3484
3485        CmsResource pseudoResource = new CmsResource(
3486            null,
3487            resourceId,
3488            null,
3489            0,
3490            false,
3491            0,
3492            null,
3493            null,
3494            0,
3495            null,
3496            0,
3497            null,
3498            0,
3499            0,
3500            0,
3501            0,
3502            0,
3503            0);
3504        return readSiblings(pseudoResource, filter);
3505    }
3506
3507    /**
3508     * Returns the parameters of a resource in the list of all published template resources.<p>
3509     *
3510     * @param rfsName the rfs name of the resource
3511     *
3512     * @return the parameter string of the requested resource
3513     *
3514     * @throws CmsException if something goes wrong
3515     */
3516    public String readStaticExportPublishedResourceParameters(String rfsName) throws CmsException {
3517
3518        return m_securityManager.readStaticExportPublishedResourceParameters(m_context, rfsName);
3519    }
3520
3521    /**
3522     * Returns a list of all template resources which must be processed during a static export.<p>
3523     *
3524     * @param parameterResources flag for reading resources with parameters (1) or without (0)
3525     *
3526     * @param timestamp a time stamp for reading the data from the db
3527     *
3528     * @return a list of template resources as <code>{@link String}</code> objects
3529     *
3530     * @throws CmsException if something goes wrong
3531     */
3532    public List<String> readStaticExportResources(int parameterResources, long timestamp) throws CmsException {
3533
3534        return m_securityManager.readStaticExportResources(m_context, parameterResources, timestamp);
3535    }
3536
3537    /**
3538     * Reads the URL name mappings matching a given filter.<p>
3539     *
3540     * @param filter the filter to match
3541     * @return the URL name mappings matching the filter
3542     *
3543     * @throws CmsException if something goes wrong
3544     */
3545    public List<CmsUrlNameMappingEntry> readUrlNameMappings(CmsUrlNameMappingFilter filter) throws CmsException {
3546
3547        return m_securityManager.readUrlNameMappings(m_context, filter);
3548    }
3549
3550    /**
3551     * Reads the URL names for all locales.<p>
3552     *
3553     * @param structureId the id of resource for which the URL names should be read
3554     * @return returns the URL names for the resource
3555     *
3556     * @throws CmsException if something goes wrong
3557     */
3558    public List<String> readUrlNamesForAllLocales(CmsUUID structureId) throws CmsException {
3559
3560        List<String> detailNames = m_securityManager.readUrlNamesForAllLocales(m_context, structureId);
3561        if (detailNames.isEmpty()) {
3562            List<String> result = new ArrayList<String>();
3563            result.add(structureId.toString());
3564            return result;
3565        }
3566        return detailNames;
3567    }
3568
3569    /**
3570     * Reads a user based on its id.<p>
3571     *
3572     * @param userId the id of the user to be read
3573     *
3574     * @return the user with the given id
3575     *
3576     * @throws CmsException if something goes wrong
3577     *
3578     * @see #readHistoryPrincipal(CmsUUID) for retrieving data of deleted users
3579     */
3580    public CmsUser readUser(CmsUUID userId) throws CmsException {
3581
3582        return m_securityManager.readUser(m_context, userId);
3583    }
3584
3585    /**
3586     * Reads a user based on its name.<p>
3587     *
3588     * @param username the name of the user to be read
3589     *
3590     * @return the user with the given name
3591     *
3592     * @throws CmsException if something goes wrong
3593     */
3594    public CmsUser readUser(String username) throws CmsException {
3595
3596        return m_securityManager.readUser(m_context, username);
3597    }
3598
3599    /**
3600     * Returns a user, if the password is correct.<p>
3601     *
3602     * If the user/pwd pair is not valid a <code>{@link CmsException}</code> is thrown.<p>
3603     *
3604     * @param username the name of the user to be returned
3605     * @param password the password of the user to be returned
3606     *
3607     * @return the validated user
3608     *
3609     * @throws CmsException if operation was not successful
3610     */
3611    public CmsUser readUser(String username, String password) throws CmsException {
3612
3613        return m_securityManager.readUser(m_context, username, password);
3614    }
3615
3616    /**
3617     * Removes a resource from the current project of the user.<p>
3618     *
3619     * This is used to reduce the current users project with the
3620     * specified resource, in case that the resource is already part of the project.
3621     * The resource is not really removed like in a regular copy operation,
3622     * it is in fact only "disabled" in the current users project.<p>
3623     *
3624     * @param resourcename the name of the resource to remove to the current project (full current site relative path)
3625     *
3626     * @throws CmsException if something goes wrong
3627     */
3628    public void removeResourceFromProject(String resourcename) throws CmsException {
3629
3630        // TODO: this should be also possible if the resource has been deleted
3631        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
3632        getResourceType(resource).removeResourceFromProject(this, m_securityManager, resource);
3633    }
3634
3635    /**
3636     * Removes a user from a group.<p>
3637     *
3638     * @param username the name of the user that is to be removed from the group
3639     * @param groupname the name of the group
3640     *
3641     * @throws CmsException if operation was not successful
3642     */
3643    public void removeUserFromGroup(String username, String groupname) throws CmsException {
3644
3645        m_securityManager.removeUserFromGroup(m_context, username, groupname, false);
3646    }
3647
3648    /**
3649     * Renames a resource to the given destination name,
3650     * this is identical to a <code>move</code> operation.<p>
3651     *
3652     * @param source the name of the resource to rename (full current site relative path)
3653     * @param destination the new resource name (full path)
3654     *
3655     * @throws CmsException if something goes wrong
3656     *
3657     * @see #moveResource(String, String)
3658     */
3659    public void renameResource(String source, String destination) throws CmsException {
3660
3661        moveResource(source, destination);
3662    }
3663
3664    /**
3665     * Replaces the content, type and properties of a resource.<p>
3666     *
3667     * @param resourcename the name of the resource to replace (full current site relative path)
3668     * @param type the new type of the resource
3669     * @param content the new content of the resource
3670     * @param properties the new properties of the resource
3671     *
3672     * @throws CmsException if something goes wrong
3673     */
3674    public void replaceResource(
3675        String resourcename,
3676        I_CmsResourceType type,
3677        byte[] content,
3678        List<CmsProperty> properties)
3679    throws CmsException {
3680
3681        CmsResource resource = readResource(resourcename, CmsResourceFilter.IGNORE_EXPIRATION);
3682        getResourceType(resource).replaceResource(this, m_securityManager, resource, type, content, properties);
3683    }
3684
3685    /**
3686     * Replaces the content, type and properties of a resource.<p>
3687     *
3688     * @param resourcename the name of the resource to replace (full current site relative path)
3689     * @param type the new type of the resource
3690     * @param content the new content of the resource
3691     * @param properties the new properties of the resource
3692     *
3693     * @throws CmsException if something goes wrong
3694     *
3695     * @deprecated
3696     * Use {@link #replaceResource(String, I_CmsResourceType, byte[], List)} instead.
3697     * Resource types should always be referenced either by its type class (preferred) or by type name.
3698     * Use of int based resource type references will be discontinued in a future OpenCms release.
3699     */
3700    @Deprecated
3701    public void replaceResource(String resourcename, int type, byte[] content, List<CmsProperty> properties)
3702    throws CmsException {
3703
3704        replaceResource(resourcename, getResourceType(type), content, properties);
3705    }
3706
3707    /**
3708     * Restores a deleted resource identified by its structure id from the historical archive.<p>
3709     *
3710     * These ids can be obtained from the {@link #readDeletedResources(String, boolean)} method.<p>
3711     *
3712     * @param structureId the structure id of the resource to restore
3713     *
3714     * @throws CmsException if something goes wrong
3715     */
3716    public void restoreDeletedResource(CmsUUID structureId) throws CmsException {
3717
3718        m_securityManager.restoreDeletedResource(m_context, structureId);
3719    }
3720
3721    /**
3722     * Restores a resource in the current project with a version from the historical archive.<p>
3723     *
3724     * @param structureId the structure id of the resource to restore from the archive
3725     * @param version the desired version of the resource to be restored
3726     *
3727     * @throws CmsException if something goes wrong
3728     *
3729     * @see #readResource(CmsUUID, int)
3730     */
3731    public void restoreResourceVersion(CmsUUID structureId, int version) throws CmsException {
3732
3733        CmsResource resource = readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION);
3734        getResourceType(resource).restoreResource(this, m_securityManager, resource, version);
3735    }
3736
3737    /**
3738     * Removes an access control entry of a given principal from a given resource.<p>
3739     *
3740     * @param resourceName name of the resource
3741     * @param principalType the type of the principal (currently group or user)
3742     * @param principalName the name of the principal
3743     *
3744     * @throws CmsException if something goes wrong
3745     */
3746    public void rmacc(String resourceName, String principalType, String principalName) throws CmsException {
3747
3748        CmsResource res = readResource(resourceName, CmsResourceFilter.ALL);
3749
3750        if (CmsUUID.isValidUUID(principalName)) {
3751            // principal name is in fact a UUID, probably the user was already deleted
3752            m_securityManager.removeAccessControlEntry(m_context, res, new CmsUUID(principalName));
3753        } else if (CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_NAME.equals(principalName)) {
3754            m_securityManager.removeAccessControlEntry(m_context, res, CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_ID);
3755        } else if (CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_NAME.equals(principalName)) {
3756            m_securityManager.removeAccessControlEntry(
3757                m_context,
3758                res,
3759                CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_ID);
3760        } else {
3761            try {
3762                // principal name not a UUID, assume this is a normal group or user name
3763                I_CmsPrincipal principal = CmsPrincipal.readPrincipal(this, principalType, principalName);
3764                m_securityManager.removeAccessControlEntry(m_context, res, principal.getId());
3765            } catch (CmsDbEntryNotFoundException e) {
3766                // role case
3767                CmsRole role = CmsRole.valueOfRoleName(principalName);
3768                if (role == null) {
3769                    throw e;
3770                }
3771                m_securityManager.removeAccessControlEntry(m_context, res, role.getId());
3772            }
3773        }
3774    }
3775
3776    /**
3777     * Changes the "expire" date of a resource.<p>
3778     *
3779     * @param resource the resource to change
3780     * @param dateExpired the new expire date of the changed resource
3781     * @param recursive if this operation is to be applied recursively to all resources in a folder
3782     *
3783     * @throws CmsException if something goes wrong
3784     */
3785    public void setDateExpired(CmsResource resource, long dateExpired, boolean recursive) throws CmsException {
3786
3787        getResourceType(resource).setDateExpired(this, m_securityManager, resource, dateExpired, recursive);
3788    }
3789
3790    /**
3791     * Changes the "expire" date of a resource.<p>
3792     *
3793     * @param resourcename the name of the resource to change (full current site relative path)
3794     * @param dateExpired the new expire date of the changed resource
3795     * @param recursive if this operation is to be applied recursively to all resources in a folder
3796     *
3797     * @throws CmsException if something goes wrong
3798     */
3799    public void setDateExpired(String resourcename, long dateExpired, boolean recursive) throws CmsException {
3800
3801        CmsResource resource = readResource(resourcename, CmsResourceFilter.IGNORE_EXPIRATION);
3802        setDateExpired(resource, dateExpired, recursive);
3803    }
3804
3805    /**
3806     * Changes the "last modified" time stamp of a resource.<p>
3807     *
3808     * @param resourcename the name of the resource to change (full current site relative path)
3809     * @param dateLastModified time stamp the new time stamp of the changed resource
3810     * @param recursive if this operation is to be applied recursively to all resources in a folder
3811     *
3812     * @throws CmsException if something goes wrong
3813     */
3814    public void setDateLastModified(String resourcename, long dateLastModified, boolean recursive) throws CmsException {
3815
3816        CmsResource resource = readResource(resourcename, CmsResourceFilter.IGNORE_EXPIRATION);
3817        getResourceType(resource).setDateLastModified(this, m_securityManager, resource, dateLastModified, recursive);
3818    }
3819
3820    /**
3821     * Changes the "release" date of a resource.<p>
3822     *
3823     * @param resource the resource to change
3824     * @param dateReleased the new release date of the changed resource
3825     * @param recursive if this operation is to be applied recursively to all resources in a folder
3826     *
3827     * @throws CmsException if something goes wrong
3828     */
3829    public void setDateReleased(CmsResource resource, long dateReleased, boolean recursive) throws CmsException {
3830
3831        getResourceType(resource).setDateReleased(this, m_securityManager, resource, dateReleased, recursive);
3832    }
3833
3834    /**
3835     * Changes the "release" date of a resource.<p>
3836     *
3837     * @param resourcename the name of the resource to change (full current site relative path)
3838     * @param dateReleased the new release date of the changed resource
3839     * @param recursive if this operation is to be applied recursively to all resources in a folder
3840     *
3841     * @throws CmsException if something goes wrong
3842     */
3843    public void setDateReleased(String resourcename, long dateReleased, boolean recursive) throws CmsException {
3844
3845        CmsResource resource = readResource(resourcename, CmsResourceFilter.IGNORE_EXPIRATION);
3846        setDateReleased(resource, dateReleased, recursive);
3847    }
3848
3849    /**
3850     * Sets a new parent-group for an already existing group.<p>
3851     *
3852     * @param groupName the name of the group that should be updated
3853     * @param parentGroupName the name of the parent group to set,
3854     *                      or <code>null</code> if the parent
3855     *                      group should be deleted.
3856     *
3857     * @throws CmsException  if operation was not successful
3858     */
3859    public void setParentGroup(String groupName, String parentGroupName) throws CmsException {
3860
3861        m_securityManager.setParentGroup(m_context, groupName, parentGroupName);
3862    }
3863
3864    /**
3865     * Sets the password for a user.<p>
3866     *
3867     * @param username the name of the user
3868     * @param newPassword the new password
3869     *
3870     * @throws CmsException if operation was not successful
3871     */
3872    public void setPassword(String username, String newPassword) throws CmsException {
3873
3874        m_securityManager.setPassword(m_context, username, newPassword);
3875    }
3876
3877    /**
3878     * Sets the password for a specified user.<p>
3879     *
3880     * @param username the name of the user
3881     * @param oldPassword the old password
3882     * @param newPassword the new password
3883     *
3884     * @throws CmsException if the user data could not be read from the database
3885     */
3886    public void setPassword(String username, String oldPassword, String newPassword) throws CmsException {
3887
3888        m_securityManager.resetPassword(m_context, username, oldPassword, newPassword);
3889    }
3890
3891    /**
3892     * Helper method to temporarily change the site root in a try-with-resources statement.
3893     *
3894     * @param siteRoot the site root to switch to
3895     * @return an AutoCloseable that restores the original site root when closed
3896     */
3897    public AutoCloseable tempChangeSiteRoot(String siteRoot) {
3898
3899        final String oldSiteRoot = m_context.getSiteRoot();
3900        m_context.setSiteRoot(siteRoot);
3901        return () -> m_context.setSiteRoot(oldSiteRoot);
3902    }
3903
3904    /**
3905     * Undeletes a resource.<p>
3906     *
3907     * Only resources that have already been published once can be undeleted,
3908     * if a "new" resource is deleted it can not be undeleted.<p>
3909     *
3910     * @param resourcename the name of the resource to undelete
3911     * @param recursive if this operation is to be applied recursively to all resources in a folder
3912     *
3913     * @throws CmsException if something goes wrong
3914     *
3915     * @see CmsObject#undoChanges(String, CmsResource.CmsResourceUndoMode)
3916     */
3917    public void undeleteResource(String resourcename, boolean recursive) throws CmsException {
3918
3919        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
3920        getResourceType(resource).undelete(this, m_securityManager, resource, recursive);
3921    }
3922
3923    /**
3924     * Undoes all changes to a resource by restoring the version from the
3925     * online project to the current offline project.<p>
3926     *
3927     * @param resourcename the name of the resource to undo the changes for
3928     * @param mode the undo mode, one of the <code>{@link CmsResource.CmsResourceUndoMode}#UNDO_XXX</code> constants
3929     *
3930     * @throws CmsException if something goes wrong
3931     *
3932     * @see CmsResource#UNDO_CONTENT
3933     * @see CmsResource#UNDO_CONTENT_RECURSIVE
3934     * @see CmsResource#UNDO_MOVE_CONTENT
3935     * @see CmsResource#UNDO_MOVE_CONTENT_RECURSIVE
3936     */
3937    public void undoChanges(String resourcename, CmsResource.CmsResourceUndoMode mode) throws CmsException {
3938
3939        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
3940        getResourceType(resource).undoChanges(this, m_securityManager, resource, mode);
3941    }
3942
3943    /**
3944     * Unlocks all resources of a project.
3945     *
3946     * @param id the id of the project to be unlocked
3947     *
3948     * @throws CmsException if operation was not successful
3949     */
3950    public void unlockProject(CmsUUID id) throws CmsException {
3951
3952        m_securityManager.unlockProject(m_context, id);
3953    }
3954
3955    /**
3956     * Unlocks a resource.<p>
3957     *
3958     * @param resource the resource to unlock
3959     *
3960     * @throws CmsException if something goes wrong
3961     */
3962    public void unlockResource(CmsResource resource) throws CmsException {
3963
3964        getResourceType(resource).unlockResource(this, m_securityManager, resource);
3965    }
3966
3967    /**
3968     * Unlocks a resource.<p>
3969     *
3970     * @param resourcename the name of the resource to unlock (full current site relative path)
3971     *
3972     * @throws CmsException if something goes wrong
3973     */
3974    public void unlockResource(String resourcename) throws CmsException {
3975
3976        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
3977        getResourceType(resource).unlockResource(this, m_securityManager, resource);
3978    }
3979
3980    /**
3981     * Updates the last login date on the given user to the current time.<p>
3982     *
3983     * @param user the user to be updated
3984     *
3985     * @throws CmsRoleViolationException if the current user does not own the rule {@link CmsRole#ACCOUNT_MANAGER} for the current project
3986     * @throws CmsException if operation was not successful
3987     */
3988    public void updateLastLoginDate(CmsUser user) throws CmsRoleViolationException, CmsException {
3989
3990        m_securityManager.updateLastLoginDate(m_context, user);
3991    }
3992
3993    /**
3994     * Tests if a user is member of the given group.<p>
3995     *
3996     * @param username the name of the user to test
3997     * @param groupname the name of the group to test
3998     *
3999     * @return <code>true</code>, if the user is in the group; or <code>false</code> otherwise
4000     *
4001     * @throws CmsException if operation was not successful
4002     */
4003    public boolean userInGroup(String username, String groupname) throws CmsException {
4004
4005        return (m_securityManager.userInGroup(m_context, username, groupname));
4006    }
4007
4008    /**
4009     * This method checks if a new password follows the rules for
4010     * new passwords, which are defined by a Class implementing the
4011     * <code>{@link org.opencms.security.I_CmsPasswordHandler}</code>
4012     * interface and configured in the opencms.properties file.<p>
4013     *
4014     * If this method throws no exception the password is valid.<p>
4015     *
4016     * @param password the new password that has to be checked
4017     *
4018     * @throws CmsSecurityException if the password is not valid
4019     */
4020    public void validatePassword(String password) throws CmsSecurityException {
4021
4022        m_securityManager.validatePassword(password);
4023    }
4024
4025    /**
4026     * Writes a resource to the OpenCms VFS, including it's content.<p>
4027     *
4028     * Applies only to resources of type <code>{@link CmsFile}</code>
4029     * i.e. resources that have a binary content attached.<p>
4030     *
4031     * Certain resource types might apply content validation or transformation rules
4032     * before the resource is actually written to the VFS. The returned result
4033     * might therefore be a modified version from the provided original.<p>
4034     *
4035     * @param resource the resource to write
4036     *
4037     * @return the written resource (may have been modified)
4038     *
4039     * @throws CmsException if something goes wrong
4040     */
4041    public CmsFile writeFile(CmsFile resource) throws CmsException {
4042
4043        return getResourceType(resource).writeFile(this, m_securityManager, resource);
4044    }
4045
4046    /**
4047     * Writes an already existing group.<p>
4048     *
4049     * The group has to be a valid OpenCms group.<br>
4050     *
4051     * The group will be completely overridden by the given data.<p>
4052     *
4053     * @param group the group that should be written
4054     *
4055     * @throws CmsException if operation was not successful
4056     */
4057    public void writeGroup(CmsGroup group) throws CmsException {
4058
4059        m_securityManager.writeGroup(m_context, group);
4060    }
4061
4062    /**
4063     * Creates a historical entry of the current project.<p>
4064     *
4065     * @param publishTag the correlative publish tag
4066     * @param publishDate the date of publishing
4067     *
4068     * @throws CmsException if operation was not successful
4069     */
4070    public void writeHistoryProject(int publishTag, long publishDate) throws CmsException {
4071
4072        m_securityManager.writeHistoryProject(m_context, publishTag, publishDate);
4073    }
4074
4075    /**
4076     * Writes an already existing project.<p>
4077     *
4078     * The project id has to be a valid OpenCms project id.<br>
4079     *
4080     * The project with the given id will be completely overridden
4081     * by the given data.<p>
4082     *
4083     * @param project the project that should be written
4084     *
4085     * @throws CmsException if operation was not successful
4086     */
4087    public void writeProject(CmsProject project) throws CmsException {
4088
4089        m_securityManager.writeProject(m_context, project);
4090    }
4091
4092    /**
4093     * Writes the 'projectlastmodified' field of a resource record.<p>
4094     *
4095     * @param resource the resource which should be modified
4096     * @param project the project whose id should be written into the resource record
4097     *
4098     * @throws CmsException if something goes wrong
4099     */
4100    public void writeProjectLastModified(CmsResource resource, CmsProject project) throws CmsException {
4101
4102        m_securityManager.writeResourceProjectLastModified(getRequestContext(), resource, project);
4103    }
4104
4105    /**
4106     * Writes a property for a specified resource.<p>
4107     *
4108     * @param resourcename the name of resource with complete path
4109     * @param property the property to write
4110     *
4111     * @throws CmsException if something goes wrong
4112     */
4113    public void writePropertyObject(String resourcename, CmsProperty property) throws CmsException {
4114
4115        CmsResource resource = readResource(resourcename, CmsResourceFilter.IGNORE_EXPIRATION);
4116        getResourceType(resource).writePropertyObject(this, m_securityManager, resource, property);
4117    }
4118
4119    /**
4120     * Writes a list of properties for a specified resource.<p>
4121     *
4122     * Code calling this method has to ensure that the no properties
4123     * <code>a, b</code> are contained in the specified list so that <code>a.equals(b)</code>,
4124     * otherwise an exception is thrown.<p>
4125     *
4126     * @param res the resource
4127     * @param properties the list of properties to write
4128     *
4129     * @throws CmsException if something goes wrong
4130     */
4131    public void writePropertyObjects(CmsResource res, List<CmsProperty> properties) throws CmsException {
4132
4133        getResourceType(res).writePropertyObjects(this, m_securityManager, res, properties);
4134    }
4135
4136    /**
4137     * Writes a list of properties for a specified resource.<p>
4138     *
4139     * Code calling this method has to ensure that the no properties
4140     * <code>a, b</code> are contained in the specified list so that <code>a.equals(b)</code>,
4141     * otherwise an exception is thrown.<p>
4142     *
4143     * @param resourcename the name of resource with complete path
4144     * @param properties the list of properties to write
4145     *
4146     * @throws CmsException if something goes wrong
4147     */
4148    public void writePropertyObjects(String resourcename, List<CmsProperty> properties) throws CmsException {
4149
4150        CmsResource resource = readResource(resourcename, CmsResourceFilter.IGNORE_EXPIRATION);
4151        getResourceType(resource).writePropertyObjects(this, m_securityManager, resource, properties);
4152    }
4153
4154    /**
4155     * Writes a resource.<p>
4156     *
4157     * @param resource the file to write
4158     *
4159     * @throws CmsException if resource type is set to folder, or
4160     *                      if the user has not the rights to write the file header.
4161     */
4162    public void writeResource(CmsResource resource) throws CmsException {
4163
4164        m_securityManager.writeResource(m_context, resource);
4165    }
4166
4167    /**
4168     * Writes a published resource entry.<p>
4169     *
4170     * This is done during static export.<p>
4171     *
4172     * @param resourceName The name of the resource to be added to the static export
4173     * @param linkType the type of resource exported (0= non-parameter, 1=parameter)
4174     * @param linkParameter the parameters added to the resource
4175     * @param timestamp a time stamp for writing the data into the db
4176     *
4177     * @throws CmsException if something goes wrong
4178     */
4179    public void writeStaticExportPublishedResource(
4180        String resourceName,
4181        int linkType,
4182        String linkParameter,
4183        long timestamp)
4184    throws CmsException {
4185
4186        m_securityManager.writeStaticExportPublishedResource(
4187            m_context,
4188            resourceName,
4189            linkType,
4190            linkParameter,
4191            timestamp);
4192    }
4193
4194    /**
4195     * Writes a new URL name mapping for a given resource.<p>
4196     *
4197     * The first name from the given name sequence which is not already mapped to another resource will be used
4198     * for the URL name mapping.<p>
4199     *
4200     * @param nameSeq an iterator for generating names for the mapping
4201     * @param structureId the structure id to which the name should be mapped
4202     * @param locale the locale of the mapping
4203     * @param replaceOnPublish if the mapping should replace previous mappings when published
4204     *
4205     * @return the name which was actually mapped to the structure id
4206     *
4207     * @throws CmsException if something goes wrong
4208     */
4209    public String writeUrlNameMapping(
4210        Iterator<String> nameSeq,
4211        CmsUUID structureId,
4212        String locale,
4213        boolean replaceOnPublish)
4214    throws CmsException {
4215
4216        return m_securityManager.writeUrlNameMapping(m_context, nameSeq, structureId, locale, replaceOnPublish);
4217    }
4218
4219    /**
4220     * Writes a new URL name mapping for a given resource.<p>
4221     *
4222     * This method uses {@link CmsNumberSuffixNameSequence} to generate a sequence of name candidates
4223     * from the given base name.<p>
4224     *
4225     * @param name the base name for the mapping
4226     * @param structureId the structure id to which the name should be mapped
4227     * @param locale the locale of the mapping
4228     * @param replaceOnPublish mappings for which this is set will replace older mappings on publish
4229     *
4230     * @return the URL name that was actually used for the mapping
4231     *
4232     * @throws CmsException if something goes wrong
4233     */
4234    public String writeUrlNameMapping(String name, CmsUUID structureId, String locale, boolean replaceOnPublish)
4235    throws CmsException {
4236
4237        return writeUrlNameMapping(new CmsNumberSuffixNameSequence(name), structureId, locale, replaceOnPublish);
4238    }
4239
4240    /**
4241     * Updates the user information. <p>
4242     *
4243     * The user id has to be a valid OpenCms user id.<br>
4244     *
4245     * The user with the given id will be completely overriden
4246     * by the given data.<p>
4247     *
4248     * @param user the user to be written
4249     *
4250     * @throws CmsException if operation was not successful
4251     */
4252    public void writeUser(CmsUser user) throws CmsException {
4253
4254        m_securityManager.writeUser(m_context, user);
4255    }
4256
4257    /**
4258     * Adds a new relation to the given resource.<p>
4259     *
4260     * @param resource the source resource
4261     * @param target the target resource
4262     * @param relationType the type of the relation
4263     * @param importCase if importing relations
4264     *
4265     * @throws CmsException if something goes wrong
4266     */
4267    private void createRelation(CmsResource resource, CmsResource target, String relationType, boolean importCase)
4268    throws CmsException {
4269
4270        CmsRelationType type = CmsRelationType.valueOf(relationType);
4271        m_securityManager.addRelationToResource(m_context, resource, target, type, importCase);
4272    }
4273
4274    /**
4275     * Adds a new relation to the given resource.<p>
4276     *
4277     * @param resourceName the name of the source resource
4278     * @param targetPath the path of the target resource
4279     * @param relationType the type of the relation
4280     * @param importCase if importing relations
4281     *
4282     * @throws CmsException if something goes wrong
4283     */
4284    private void createRelation(String resourceName, String targetPath, String relationType, boolean importCase)
4285    throws CmsException {
4286
4287        CmsResource resource = readResource(resourceName, CmsResourceFilter.IGNORE_EXPIRATION);
4288        CmsResource target = readResource(targetPath, CmsResourceFilter.IGNORE_EXPIRATION);
4289        createRelation(resource, target, relationType, importCase);
4290    }
4291
4292    /**
4293     * Notify all event listeners that a particular event has occurred.<p>
4294     *
4295     * The event will be given to all registered <code>{@link I_CmsEventListener}</code>s.<p>
4296     *
4297     * @param type the type of the event
4298     * @param data a data object that contains data used by the event listeners
4299     *
4300     * @see OpenCms#addCmsEventListener(I_CmsEventListener)
4301     * @see OpenCms#addCmsEventListener(I_CmsEventListener, int[])
4302     */
4303    private void fireEvent(int type, Object data) {
4304
4305        OpenCms.fireCmsEvent(type, Collections.singletonMap("data", data));
4306    }
4307
4308    /**
4309     * Convenience method to get the initialized resource type instance for the given resource,
4310     * with a fall back to special "unknown" resource types in case the resource type is not configured.<p>
4311     *
4312     * @param resource the resource to get the type for
4313     *
4314     * @return the initialized resource type instance for the given resource
4315     *
4316     * @see org.opencms.loader.CmsResourceManager#getResourceType(int)
4317     */
4318    private I_CmsResourceType getResourceType(CmsResource resource) {
4319
4320        return OpenCms.getResourceManager().getResourceType(resource);
4321    }
4322
4323    /**
4324     * Convenience method to return the initialized resource type
4325     * instance for the given id.<p>
4326     *
4327     * @param resourceType the id of the resource type to get
4328     *
4329     * @return the initialized resource type instance for the given id
4330     *
4331     * @throws CmsException if something goes wrong
4332     *
4333     * @see org.opencms.loader.CmsResourceManager#getResourceType(int)
4334     */
4335    private I_CmsResourceType getResourceType(int resourceType) throws CmsException {
4336
4337        return OpenCms.getResourceManager().getResourceType(resourceType);
4338    }
4339
4340    /**
4341     * Initializes this <code>{@link CmsObject}</code> with the provided user context and database connection.<p>
4342     *
4343     * @param securityManager the security manager
4344     * @param context the request context that contains the user authentication
4345     */
4346    private void init(CmsSecurityManager securityManager, CmsRequestContext context) {
4347
4348        m_securityManager = securityManager;
4349        m_context = context;
4350    }
4351
4352    /**
4353     * Locks a resource.<p>
4354     *
4355     * The <code>type</code> parameter controls what kind of lock is used.<br>
4356     * Possible values for this parameter are: <br>
4357     * <ul>
4358     * <li><code>{@link org.opencms.lock.CmsLockType#EXCLUSIVE}</code></li>
4359     * <li><code>{@link org.opencms.lock.CmsLockType#TEMPORARY}</code></li>
4360     * </ul><p>
4361     *
4362     * @param resourcename the name of the resource to lock (full current site relative path)
4363     * @param type type of the lock
4364     *
4365     * @throws CmsException if something goes wrong
4366     */
4367    private void lockResource(String resourcename, CmsLockType type) throws CmsException {
4368
4369        // throw the exception if resource name is an empty string
4370        if (CmsStringUtil.isEmptyOrWhitespaceOnly(resourcename)) {
4371            throw new CmsVfsResourceNotFoundException(
4372                Messages.get().container(Messages.ERR_LOCK_RESOURCE_1, resourcename));
4373        }
4374        CmsResource resource = readResource(resourcename, CmsResourceFilter.ALL);
4375        getResourceType(resource).lockResource(this, m_securityManager, resource, type);
4376    }
4377
4378}