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