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