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