001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software GmbH & Co. KG, please see the
018 * company website: https://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: https://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.db;
029
030import org.opencms.db.storage.I_CmsStorageDelivery;
031import org.opencms.db.urlname.CmsUrlNameMappingEntry;
032import org.opencms.db.urlname.CmsUrlNameMappingFilter;
033import org.opencms.file.CmsDataAccessException;
034import org.opencms.file.CmsFile;
035import org.opencms.file.CmsFolder;
036import org.opencms.file.CmsProject;
037import org.opencms.file.CmsProperty;
038import org.opencms.file.CmsPropertyDefinition;
039import org.opencms.file.CmsResource;
040import org.opencms.file.CmsStoredContentInfo;
041import org.opencms.file.I_CmsFileContentStreamHandler;
042import org.opencms.file.quota.CmsFolderSizeEntry;
043import org.opencms.file.quota.CmsFolderSizeOptions;
044import org.opencms.relations.CmsRelation;
045import org.opencms.relations.CmsRelationFilter;
046import org.opencms.security.CmsOrganizationalUnit;
047import org.opencms.util.CmsUUID;
048
049import java.io.ByteArrayInputStream;
050import java.io.OutputStream;
051import java.sql.ResultSet;
052import java.sql.SQLException;
053import java.util.Collection;
054import java.util.List;
055import java.util.Map;
056
057/**
058 * Definitions of all required VFS driver methods.<p>
059 *
060 * @since 6.0.0
061 */
062public interface I_CmsVfsDriver {
063
064    /** The type ID to identify user driver implementations. */
065    int DRIVER_TYPE_ID = 3;
066
067    /** The internal request attribute to indicate that the permissions have to be checked. */
068    String REQ_ATTR_CHECK_PERMISSIONS = "CHECK_PERMISSIONS";
069
070    /** The internal request attribute to indicate that resource organizational units have to be retrieved. */
071    String REQ_ATTR_RESOURCE_OUS = "RETRIEVE_RESOURCE_OUS";
072
073    /**
074     * Adds a new URL name mapping entry.<p>
075     *
076     * @param dbc the current database context
077     * @param online if true, writes to the online tables, else to the offline tables
078     * @param entry the entry to add
079     *
080     * @throws CmsDataAccessException if something goes wrong
081     */
082    void addUrlNameMappingEntry(CmsDbContext dbc, boolean online, CmsUrlNameMappingEntry entry)
083    throws CmsDataAccessException;
084
085    /**
086     * Counts the number of siblings of a resource.<p>
087     *
088     * @param dbc the current database context
089     * @param projectId the current project id
090     * @param resourceId the resource id to count the number of siblings from
091     *
092     * @return number of siblings
093     * @throws CmsDataAccessException if something goes wrong
094     */
095    int countSiblings(CmsDbContext dbc, CmsUUID projectId, CmsUUID resourceId) throws CmsDataAccessException;
096
097    /**
098     * Creates a content entry for the specified resource.<p>
099     *
100     * @param dbc the current database context
101     * @param projectId the id of the current project
102     * @param resource the resource to create the content for
103     * @param content the content to write
104     *
105     * @throws CmsDataAccessException if something goes wrong
106     */
107    void createContent(CmsDbContext dbc, CmsUUID projectId, CmsResource resource, byte[] content)
108    throws CmsDataAccessException;
109
110    /**
111     * Creates a {@link CmsFile} instance from a JDBC ResultSet.<p>
112     *
113     * @param dbc the current database context
114     * @param res the JDBC ResultSet
115     * @param projectId the project id
116     *
117     * @return the created file
118     * @throws CmsDataAccessException if something goes wrong
119     * @throws SQLException in case the result set does not include a requested table attribute
120     */
121    CmsFile createFile(CmsDbContext dbc, ResultSet res, CmsUUID projectId) throws CmsDataAccessException, SQLException;
122
123    /**
124     * Creates a {@link CmsFile} instance from a JDBC ResultSet.<p>
125     *
126     * @param dbc the current database context
127     * @param res the JDBC ResultSet
128     * @param projectId the project id
129     * @param hasFileContentInResultSet flag to include the file content
130     *
131     * @return the created file
132     * @throws CmsDataAccessException if something goes wrong
133     * @throws SQLException in case the result set does not include a requested table attribute
134     */
135    CmsFile createFile(CmsDbContext dbc, ResultSet res, CmsUUID projectId, boolean hasFileContentInResultSet)
136    throws CmsDataAccessException, SQLException;
137
138    /**
139     * Creates a {@link CmsFolder} instance from a JDBC ResultSet.<p>
140     *
141     * @param res the JDBC ResultSet
142     * @param projectId the ID of the current project
143     * @param hasProjectIdInResultSet true if the SQL select query includes the PROJECT_ID table attribute
144     *
145     * @return the created folder
146     * @throws SQLException in case the result set does not include a requested table attribute
147     */
148    CmsFolder createFolder(ResultSet res, CmsUUID projectId, boolean hasProjectIdInResultSet) throws SQLException;
149
150    /**
151     * Creates a new content in the offline project.<p>
152     *
153     * @param dbc the current database context
154     * @param resourceId the resource id of the content to write
155     * @param contents the content to publish
156     * @param publishTag the publish tag
157     * @param keepOnline if the content is online or has to be put in the history
158     * @param needToUpdateContent if the content blob has to be updated
159     *
160     * @throws CmsDataAccessException if something goes wrong
161     */
162    void createOnlineContent(
163        CmsDbContext dbc,
164        CmsUUID resourceId,
165        byte[] contents,
166        int publishTag,
167        boolean keepOnline,
168        boolean needToUpdateContent)
169    throws CmsDataAccessException;
170
171    /**
172     * Creates a new property definition in the database.<p>
173     *
174     * @param dbc the current database context
175     * @param projectId the project in which the property definition is created
176     * @param name the name of the property definition
177     * @param type the type of the property definition
178     *
179     * @return the new property definition
180     *
181     * @throws CmsDataAccessException if something goes wrong
182     */
183    CmsPropertyDefinition createPropertyDefinition(
184        CmsDbContext dbc,
185        CmsUUID projectId,
186        String name,
187        CmsPropertyDefinition.CmsPropertyType type)
188    throws CmsDataAccessException;
189
190    /**
191     * Creates a new {@link CmsRelation} object in the database.<p>
192     *
193     * @param dbc the current database context
194     * @param projectId the id of the project to execute the query in
195     * @param relation the relation to create
196     *
197     * @throws CmsDataAccessException if something goes wrong
198     */
199    void createRelation(CmsDbContext dbc, CmsUUID projectId, CmsRelation relation) throws CmsDataAccessException;
200
201    /**
202     * Creates a new resource from a given {@link CmsResource} object.<p>
203     *
204     * This method works for both files and folders. Existing resources get overwritten.<p>
205     *
206     * @param dbc the current database context
207     * @param projectId the id of the current project
208     * @param resource the resource to be created
209     * @param content the file content, or null in case of a folder
210     * @return the created Cms resource
211     *
212     * @throws CmsDataAccessException if something goes wrong
213     *
214     * @see org.opencms.file.types.I_CmsResourceType#createResource(org.opencms.file.CmsObject, CmsSecurityManager, String, byte[], List)
215     * @see org.opencms.file.types.I_CmsResourceType#importResource(org.opencms.file.CmsObject, CmsSecurityManager, org.opencms.report.I_CmsReport, String, CmsResource, byte[], List)
216     * @see org.opencms.file.CmsObject#createResource(String, int, byte[], List)
217     * @see org.opencms.file.CmsObject#importResource(String, CmsResource, byte[], List)
218     */
219    CmsResource createResource(CmsDbContext dbc, CmsUUID projectId, CmsResource resource, byte[] content)
220    throws CmsDataAccessException;
221
222    /**
223     * Creates a CmsResource instance from a JDBC ResultSet.<p>
224     *
225     * @param res the JDBC ResultSet
226     * @param projectId the ID of the current project to adjust the modification date in case the resource is a VFS link
227     *
228     * @return the created resource
229     * @throws SQLException in case the result set does not include a requested table attribute
230     */
231    CmsResource createResource(ResultSet res, CmsUUID projectId) throws SQLException;
232
233    /**
234     * Creates a new sibling for a specified resource.<p>
235     * @param dbc the current database context
236     * @param project the project where to create the link
237     * @param resource the link prototype
238     *
239     * @throws CmsDataAccessException if something goes wrong
240     */
241    void createSibling(CmsDbContext dbc, CmsProject project, CmsResource resource) throws CmsDataAccessException;
242
243    /**
244     * Deletes the aliases matching a given filter.<p>
245     *
246     * @param dbc the database context
247     * @param project the current project
248     * @param filter the alias filter
249     * @throws CmsDataAccessException if something goes wrong
250     */
251    void deleteAliases(CmsDbContext dbc, CmsProject project, CmsAliasFilter filter) throws CmsDataAccessException;
252
253    /**
254     * Deletes historical content entries for a resource older than the given publish tag.<p>
255     *
256     * @param dbc the current database context
257     * @param resourceId the id of the resource
258     * @param publishTagToKeep the minimal publish tag to keep
259     *
260     * @throws CmsDataAccessException if something goes wrong
261     */
262    void deleteHistoryContent(CmsDbContext dbc, CmsUUID resourceId, int publishTagToKeep) throws CmsDataAccessException;
263
264    /**
265     * Deletes a property definition.<p>
266     *
267     * @param dbc the current database context
268     * @param name the property definitions to be deleted
269     *
270     * @throws CmsDataAccessException if something goes wrong
271     */
272    void deletePropertyDefinition(CmsDbContext dbc, CmsPropertyDefinition name) throws CmsDataAccessException;
273
274    /**
275     * Deletes all property values of a file or folder.<p>
276     *
277     * You may specify which whether just structure or resource property values should
278     * be deleted, or both of them.<p>
279     *
280     * @param dbc the current database context
281     * @param projectId the id of the project
282     * @param resource the resource
283     * @param deleteOption determines which property values should be deleted
284     *
285     * @throws CmsDataAccessException if something goes wrong
286     *
287     * @see org.opencms.file.CmsProperty#DELETE_OPTION_DELETE_STRUCTURE_AND_RESOURCE_VALUES
288     * @see org.opencms.file.CmsProperty#DELETE_OPTION_DELETE_STRUCTURE_VALUES
289     * @see org.opencms.file.CmsProperty#DELETE_OPTION_DELETE_RESOURCE_VALUES
290     */
291    void deletePropertyObjects(CmsDbContext dbc, CmsUUID projectId, CmsResource resource, int deleteOption)
292    throws CmsDataAccessException;
293
294    /**
295     * Deletes all relations with the given filter for the given resource.<p>
296     *
297     * @param dbc the current database context
298     * @param projectId the id of the project to execute the query in
299     * @param resource the base resource. May be <code>null</code> for all
300     * @param filter the filter to restrict the relations to remove
301     *
302     * @throws CmsDataAccessException if something goes wrong
303     */
304    void deleteRelations(CmsDbContext dbc, CmsUUID projectId, CmsResource resource, CmsRelationFilter filter)
305    throws CmsDataAccessException;
306
307    /**
308     * Deletes rewrite aliases matching a given filter.<p>
309     *
310     * @param dbc the current database context
311     * @param filter the filter describing which rewrite aliases to delete
312     *
313     * @throws CmsDataAccessException if something goes wrong
314     */
315    void deleteRewriteAliases(CmsDbContext dbc, CmsRewriteAliasFilter filter) throws CmsDataAccessException;
316
317    /**
318     * Deletes the URL name mapping entries which match a given filter.<p>
319     *
320     * @param dbc the current database context
321     * @param online if true, changes the online URL name mappings, else the offline URL name mappings
322     * @param filter the URL name mapping entries to delete
323     *
324     * @throws CmsDataAccessException if something goes wrong
325     */
326    void deleteUrlNameMappingEntries(CmsDbContext dbc, boolean online, CmsUrlNameMappingFilter filter)
327    throws CmsDataAccessException;
328
329    /**
330     * Destroys this driver.<p>
331     *
332     * @throws Throwable if something goes wrong
333     */
334    void destroy() throws Throwable;
335
336    /**
337     * Returns all organizational units for the given resource.<p>
338     *
339     * @param dbc the database context
340     * @param projectId the id of the project
341     * @param resource the resource
342     *
343     * @return a list of {@link org.opencms.security.CmsOrganizationalUnit} objects
344     *
345     * @throws CmsDataAccessException if something goes wrong
346     */
347    List<CmsOrganizationalUnit> getResourceOus(CmsDbContext dbc, CmsUUID projectId, CmsResource resource)
348    throws CmsDataAccessException;
349
350    /**
351     * Returns the SqlManager of this driver.<p>
352     *
353     * @return the SqlManager of this driver
354     */
355    CmsSqlManager getSqlManager();
356
357    /**
358     * Returns a delivery-capable storage backend by its stable storage identifier.<p>
359     *
360     * @param dbc the current database context
361     * @param storage the stable storage identifier
362     *
363     * @return the delivery-capable storage backend, or <code>null</code> if not supported by the VFS driver
364     *
365     * @throws CmsDataAccessException if something goes wrong
366     */
367    default I_CmsStorageDelivery getStoredContentDelivery(CmsDbContext dbc, String storage)
368    throws CmsDataAccessException {
369
370        return null;
371    }
372
373    /**
374     * Gets the current value of a counter, creates it if it doesn't already exist, and increments it.<p>
375     *
376     * @param dbc the database context
377     * @param name the name of the counter
378     *
379     * @return the counter value before incrementing
380     *
381     * @throws CmsDataAccessException if something goes wrong
382     */
383    int incrementCounter(CmsDbContext dbc, String name) throws CmsDataAccessException;
384
385    /**
386     * Initializes the SQL manager for this driver.<p>
387     *
388     * To obtain JDBC connections from different pools, further
389     * {online|offline|history} pool Urls have to be specified.<p>
390     *
391     * @param classname the class name of the SQL manager
392     *
393     * @return the SQL manager for this driver
394     */
395    CmsSqlManager initSqlManager(String classname);
396
397    /**
398     * Adds an alias to the database.<p>
399     *
400     * @param dbc the current database context
401     * @param project the current project
402     * @param alias the alias to write
403     *
404     * @throws CmsDataAccessException if something goes wrong
405     */
406    void insertAlias(CmsDbContext dbc, CmsProject project, CmsAlias alias) throws CmsDataAccessException;
407
408    /**
409     * Adds a list of rewrite aliases.<p>
410     *
411     * When adding a rewrite alias, make sure that no alias with the same id is present in the database.<p>
412     *
413     * @param dbc the current database context
414     * @param rewriteAliases the rewrite aliases to save
415     *
416     * @throws CmsDataAccessException if something goes wrong
417     */
418    void insertRewriteAliases(CmsDbContext dbc, Collection<CmsRewriteAlias> rewriteAliases)
419    throws CmsDataAccessException;
420
421    /**
422     * Moves the given resource to the specified destination path.<p>
423     *
424     * @param dbc the current database context
425     * @param projectId the Id of the project
426     * @param source the resource to move
427     * @param destinationPath the root path of the destination resource
428     *
429     * @throws CmsDataAccessException if something goes wrong
430     */
431    void moveResource(CmsDbContext dbc, CmsUUID projectId, CmsResource source, String destinationPath)
432    throws CmsDataAccessException;
433
434    /**
435     * Publishes the structure and resource records of an
436     * offline resource into it's online counterpart.<p>
437     *
438     * @param dbc the current database context
439     * @param onlineProject the online project
440     * @param onlineResource the online resource
441     * @param offlineResource the offline resource
442     *
443     * @throws CmsDataAccessException if something goes wrong
444     */
445    void publishResource(
446        CmsDbContext dbc,
447        CmsProject onlineProject,
448        CmsResource onlineResource,
449        CmsResource offlineResource)
450    throws CmsDataAccessException;
451
452    /**
453     * Copies the version number from the offline resource to the online resource,
454     * this has to be done during publishing, direct after copying the resource itself.<p>
455     *
456     * @param dbc the current database context
457     * @param resource the resource that has been publish
458     * @param firstSibling if this is the first sibling to be publish
459     *
460     * @throws CmsDataAccessException if something goes wrong
461     */
462    void publishVersions(CmsDbContext dbc, CmsResource resource, boolean firstSibling) throws CmsDataAccessException;
463
464    /**
465     * Reads the aliases matching a given filter.<p>
466     *
467     * @param dbc the database context
468     * @param project the current project
469     * @param filter the alias filter
470     * @return the list of aliases which were read
471     *
472     * @throws CmsDataAccessException if something goes wrong
473     */
474    List<CmsAlias> readAliases(CmsDbContext dbc, CmsProject project, CmsAliasFilter filter)
475    throws CmsDataAccessException;
476
477    /**
478     * Reads all child-files and/or child-folders of a specified parent resource.<p>
479     *
480     * @param dbc the current database context
481     * @param currentProject the current project
482     * @param resource the parent folder
483     * @param getFolders if true the child folders of the parent folder are returned in the result set
484     * @param getFiles if true the child files of the parent folder are returned in the result set
485     *
486     * @return a list of all sub folders or sub files
487     * @throws CmsDataAccessException if something goes wrong
488     */
489    List<CmsResource> readChildResources(
490        CmsDbContext dbc,
491        CmsProject currentProject,
492        CmsResource resource,
493        boolean getFolders,
494        boolean getFiles)
495    throws CmsDataAccessException;
496
497    /**
498     * Reads the content of a file specified by it's resource ID.<p>
499     *
500     * @param dbc the current database context
501     * @param projectId the ID of the current project
502     * @param resourceId the id of the resource
503     *
504     * @return the file content
505     *
506     * @throws CmsDataAccessException if something goes wrong
507     */
508    byte[] readContent(CmsDbContext dbc, CmsUUID projectId, CmsUUID resourceId) throws CmsDataAccessException;
509
510    /**
511     * Reads the content of a file specified by it's resource ID and passes it to an input stream handler.<p>
512     *
513     * @param dbc the current database context
514     * @param projectId the ID of the current project
515     * @param resourceId the id of the resource
516     * @param handler the stream handler
517     *
518     * @throws CmsDataAccessException if something goes wrong
519     */
520    default void readContentFrom(
521        CmsDbContext dbc,
522        CmsUUID projectId,
523        CmsUUID resourceId,
524        I_CmsFileContentStreamHandler handler)
525    throws CmsDataAccessException {
526
527        byte[] content = readContent(dbc, projectId, resourceId);
528        if (content == null) {
529            return;
530        }
531        try (ByteArrayInputStream in = new ByteArrayInputStream(content)) {
532            handler.read(in);
533        } catch (Exception e) {
534            throw new CmsDataAccessException(
535                Messages.get().container(
536                    Messages.ERR_READ_CONTENT_WITH_RESOURCE_ID_2,
537                    resourceId,
538                    Boolean.valueOf(projectId.equals(CmsProject.ONLINE_PROJECT_ID))),
539                e);
540        }
541    }
542
543    /**
544     * Reads the content of a file specified by it's resource ID and writes it to an output stream.<p>
545     *
546     * @param dbc the current database context
547     * @param projectId the ID of the current project
548     * @param resourceId the id of the resource
549     * @param out the output stream to write to
550     *
551     * @throws CmsDataAccessException if something goes wrong
552     */
553    default void readContentTo(CmsDbContext dbc, CmsUUID projectId, CmsUUID resourceId, OutputStream out)
554    throws CmsDataAccessException {
555
556        try {
557            out.write(readContent(dbc, projectId, resourceId));
558        } catch (Exception e) {
559            throw new CmsDataAccessException(
560                Messages.get().container(
561                    Messages.ERR_READ_CONTENT_WITH_RESOURCE_ID_2,
562                    resourceId,
563                    Boolean.valueOf(projectId.equals(CmsProject.ONLINE_PROJECT_ID))),
564                e);
565        }
566    }
567
568    /**
569     * Reads a folder specified by it's structure ID.<p>
570     *
571     * @param dbc the current database context
572     * @param projectId the project in which the resource will be used
573     * @param folderId the structure id of the folder to be read
574     *
575     * @return the read folder
576     *
577     * @throws CmsDataAccessException if something goes wrong
578     */
579    CmsFolder readFolder(CmsDbContext dbc, CmsUUID projectId, CmsUUID folderId) throws CmsDataAccessException;
580
581    /**
582     * Reads a folder specified by it's resource name.<p>
583     *
584     * @param dbc the current database context
585     * @param projectId the project in which the resource will be used
586     * @param foldername the name of the folder to be read
587     *
588     * @return the read folder
589     * @throws CmsDataAccessException if something goes wrong
590     */
591    CmsFolder readFolder(CmsDbContext dbc, CmsUUID projectId, String foldername) throws CmsDataAccessException;
592
593    /**
594     * Reads folder size statistics for the subtree at a given root path.
595     *
596     * @param dbc tje database context
597     * @param online true if we want the online data, false for the offline data
598     * @param options the options on what exactly to read
599     *
600     * @return the list of folder size beans
601     *
602     * @throws CmsDataAccessException if something goes wrong
603     */
604    List<CmsFolderSizeEntry> readFolderSizeStats(CmsDbContext dbc, boolean online, CmsFolderSizeOptions options)
605    throws CmsDataAccessException;
606
607    /**
608     * Reads the historical content of a file specified by its resource ID and publish tag.<p>
609     *
610     * @param dbc the current database context
611     * @param resourceId the id of the resource
612     * @param publishTag the publish tag of the historical content
613     *
614     * @return the historical file content
615     *
616     * @throws CmsDataAccessException if something goes wrong
617     */
618    byte[] readHistoryContent(CmsDbContext dbc, CmsUUID resourceId, int publishTag) throws CmsDataAccessException;
619
620    /**
621     * Reads the parent folder of a resource specified by it's structure ID.<p>
622     *
623     * The parent folder for the root '/' is defined as <code>null</code>.<p>
624     *
625     * @param dbc the current database context
626     * @param projectId the project in which the resource will be used
627     * @param structureId the id of the resource to read the parent folder for
628     *
629     * @return the read folder, or <code>null</code>
630     *
631     * @throws CmsDataAccessException if something goes wrong
632     */
633    CmsFolder readParentFolder(CmsDbContext dbc, CmsUUID projectId, CmsUUID structureId) throws CmsDataAccessException;
634
635    /**
636     * Reads a property definition for the specified resource type.<p>
637     *
638     * If no property definition with the given name is found,
639     * <code>null</code> is returned.<p>
640     *
641     * @param dbc the current database context
642     * @param name the name of the property definition to read
643     * @param projectId the id of the project
644     *
645     * @return the property definition that was read
646     *
647     * @throws CmsDataAccessException a CmsDbEntryNotFoundException is thrown if the property definition does not exist
648     */
649    CmsPropertyDefinition readPropertyDefinition(CmsDbContext dbc, String name, CmsUUID projectId)
650    throws CmsDataAccessException;
651
652    /**
653     * Reads all property definitions for the specified mapping type.<p>
654     *
655     * @param dbc the current database context
656     * @param projectId the id of the project
657     *
658     * @return a list with the <code>{@link CmsPropertyDefinition}</code> objects (may be empty)
659     *
660     * @throws CmsDataAccessException if something goes wrong
661     */
662    List<CmsPropertyDefinition> readPropertyDefinitions(CmsDbContext dbc, CmsUUID projectId)
663    throws CmsDataAccessException;
664
665    /**
666     * Reads a property object from the database specified by it's key name mapped to a resource.<p>
667     *
668     * The implementation must return {@link CmsProperty#getNullProperty()} if the property is not found.<p>
669     *
670     * TODO: change project parameter to project id
671     *
672     * @param dbc the current database context
673     * @param key the key of the property
674     * @param project the current project
675     * @param resource the resource where the property is attached to
676     *
677     * @return a CmsProperty object containing both the structure and resource value of the property
678     *
679     * @throws CmsDataAccessException if something goes wrong
680     */
681    CmsProperty readPropertyObject(CmsDbContext dbc, String key, CmsProject project, CmsResource resource)
682    throws CmsDataAccessException;
683
684    /**
685     * Reads all property objects mapped to a specified resource from the database.<p>
686     *
687     * The implementation must return an empty list if no properties are found at all.<p>
688     *
689     * TODO: change project parameter to project id
690     *
691     * @param dbc the current database context
692     * @param project the current project
693     * @param resource the resource where the property is attached to
694     *
695     * @return a list with CmsProperty objects containing both the structure and resource value of the property
696     * @throws CmsDataAccessException if something goes wrong
697     */
698    List<CmsProperty> readPropertyObjects(CmsDbContext dbc, CmsProject project, CmsResource resource)
699    throws CmsDataAccessException;
700
701    /**
702     * Reads all relations with the given filter for the given resource.<p>
703     *
704     * @param dbc the current database context
705     * @param projectId the id of the project to execute the query in
706     * @param resource the resource to read the relations for, may be <code>null</code> for all
707     * @param filter the filter to restrict the relations to retrieve
708     *
709     * @return the read relations
710     *
711     * @throws CmsDataAccessException if something goes wrong
712     */
713    List<CmsRelation> readRelations(CmsDbContext dbc, CmsUUID projectId, CmsResource resource, CmsRelationFilter filter)
714    throws CmsDataAccessException;
715
716    /**
717     * Reads a resource specified by it's structure ID.<p>
718     *
719     * @param dbc the current database context
720     * @param projectId the Id of the project
721     * @param structureId the Id of the resource
722     * @param includeDeleted true if already deleted files are included
723     *
724     * @return the resource that was read
725     * @throws CmsDataAccessException if something goes wrong
726     */
727    CmsResource readResource(CmsDbContext dbc, CmsUUID projectId, CmsUUID structureId, boolean includeDeleted)
728    throws CmsDataAccessException;
729
730    /**
731     * Reads a resource specified by it's resource name.<p>
732     *
733     * @param dbc the current database context
734     * @param projectId the Id of the project in which the resource will be used
735     * @param filename the name of the file
736     * @param includeDeleted true if already deleted files are included
737     *
738     * @return the resource that was read
739     * @throws CmsDataAccessException if something goes wrong
740     */
741    CmsResource readResource(CmsDbContext dbc, CmsUUID projectId, String filename, boolean includeDeleted)
742    throws CmsDataAccessException;
743
744    /**
745     * Reads all resources inside a given project and with a given state.<p>
746     *
747     * @param dbc the current database context
748     * @param currentProject the current project
749     * @param state the state to match
750     * @param mode flag signaling the read mode
751     *
752     * @return a list with all resources that where read
753     * @throws CmsDataAccessException if something goes wrong
754     */
755    List<CmsResource> readResources(CmsDbContext dbc, CmsUUID currentProject, CmsResourceState state, int mode)
756    throws CmsDataAccessException;
757
758    /**
759     * Returns all resources associated to a given principal via an ACE.<p>
760     *
761     * @param dbc the current database context
762     * @param project the to read the entries from
763     * @param principalId the id of the principal
764     *
765     * @return a list of <code>{@link org.opencms.file.CmsResource}</code> objects
766     *
767     * @throws CmsDataAccessException if something goes wrong
768     */
769    List<CmsResource> readResourcesForPrincipalACE(CmsDbContext dbc, CmsProject project, CmsUUID principalId)
770    throws CmsDataAccessException;
771
772    /**
773     * Returns all resources associated to a given principal through some of following attributes.<p>
774     *
775     * <ul>
776     *    <li>User Created</li>
777     *    <li>User Last Modified</li>
778     * </ul><p>
779     *
780     * @param dbc the current database context
781     * @param project the to read the entries from
782     * @param principalId the id of the principal
783     *
784     * @return a list of <code>{@link org.opencms.file.CmsResource}</code> objects
785     *
786     * @throws CmsDataAccessException if something goes wrong
787     */
788    List<CmsResource> readResourcesForPrincipalAttr(CmsDbContext dbc, CmsProject project, CmsUUID principalId)
789    throws CmsDataAccessException;
790
791    /**
792     * Reads all resources that have a value (containing the specified value)
793     * set for the specified property (definition), in the given path.<p>
794     *
795     * Both individual and shared properties of a resource are checked.<p>
796     *
797     * If the <code>value</code> parameter is <code>null</code>, all resources having the
798     * given property set are returned.<p>
799     *
800     * @param dbc the current database context
801     * @param projectId the id of the project
802     * @param propertyDefinition the id of the property definition
803     * @param path the folder to get the resources with the property from
804     * @param value the string to search in the value of the property
805     *
806     * @return a list of all <code>{@link CmsResource}</code> objects
807     *          that have a value set for the specified property.
808     *
809     * @throws CmsDataAccessException if something goes wrong
810     */
811    List<CmsResource> readResourcesWithProperty(
812        CmsDbContext dbc,
813        CmsUUID projectId,
814        CmsUUID propertyDefinition,
815        String path,
816        String value)
817    throws CmsDataAccessException;
818
819    /**
820     * Reads all resources inside a given project matching the criteria specified by parameter values.<p>
821     *
822     * Important: If {@link CmsDriverManager#READMODE_EXCLUDE_TREE} is true (or {@link CmsDriverManager#READMODE_INCLUDE_TREE} is false),
823     * the provided parent String must be the UUID of the parent folder, NOT the parent folder path.<p>
824     *
825     * @param dbc the current database context
826     * @param projectId the project id for matching resources
827     * @param parent the path to the resource used as root of the searched subtree or {@link CmsDriverManager#READ_IGNORE_PARENT},
828     *               {@link CmsDriverManager#READMODE_EXCLUDE_TREE} means to read immediate children only
829     * @param type the resource type of matching resources or {@link CmsDriverManager#READ_IGNORE_TYPE} (meaning inverted by {@link CmsDriverManager#READMODE_EXCLUDE_TYPE}
830     * @param state the state of matching resources (meaning inverted by {@link CmsDriverManager#READMODE_EXCLUDE_STATE} or <code>null</code> to ignore
831     * @param startTime the start of the time range for the last modification date of matching resources or READ_IGNORE_TIME
832     * @param endTime the end of the time range for the last modification date of matching resources or READ_IGNORE_TIME
833     * @param releasedAfter the start of the time range for the release date of matching resources
834     * @param releasedBefore the end of the time range for the release date of matching resources
835     * @param expiredAfter the start of the time range for the expire date of matching resources
836     * @param expiredBefore the end of the time range for the expire date of matching resources
837     * @param mode additional mode flags:
838     * <ul>
839     *  <li>{@link CmsDriverManager#READMODE_INCLUDE_TREE}
840     *  <li>{@link CmsDriverManager#READMODE_EXCLUDE_TREE}
841     *  <li>{@link CmsDriverManager#READMODE_INCLUDE_PROJECT}
842     *  <li>{@link CmsDriverManager#READMODE_EXCLUDE_TYPE}
843     *  <li>{@link CmsDriverManager#READMODE_EXCLUDE_STATE}
844     * </ul>
845     *
846     * @return a list of CmsResource objects matching the given criteria
847     *
848     * @throws CmsDataAccessException if something goes wrong
849     */
850    List<CmsResource> readResourceTree(
851        CmsDbContext dbc,
852        CmsUUID projectId,
853        String parent,
854        int type,
855        CmsResourceState state,
856        long startTime,
857        long endTime,
858        long releasedAfter,
859        long releasedBefore,
860        long expiredAfter,
861        long expiredBefore,
862        int mode)
863    throws CmsDataAccessException;
864
865    /**
866     * Reads the rewrite aliases matching a given filter.<p>
867     *
868     * @param dbc the current database context
869     * @param filter the filter describing which rewrite aliases should be returned
870     *
871     * @return the rewrite aliases which were found
872     *
873     * @throws CmsDataAccessException if something goes wrong
874     */
875    List<CmsRewriteAlias> readRewriteAliases(CmsDbContext dbc, CmsRewriteAliasFilter filter)
876    throws CmsDataAccessException;
877
878    /**
879     * Reads all siblings that point to the resource record of a specified resource.<p>
880     *
881     * @param dbc the current database context
882     * @param projectId the id of the current project
883     * @param resource the specified resource
884     * @param includeDeleted <code>true</code> if deleted siblings should be included in the result list
885     *
886     * @return a list of <code>{@link CmsResource}</code>s that
887     *          are siblings to the specified resource,
888     *          including the specified resource itself.
889     *
890     * @throws CmsDataAccessException if something goes wrong
891     */
892    List<CmsResource> readSiblings(CmsDbContext dbc, CmsUUID projectId, CmsResource resource, boolean includeDeleted)
893    throws CmsDataAccessException;
894
895    /**
896     * Reads information about where the content for a file resource is stored without loading the content bytes.<p>
897     *
898     * @param dbc the current database context
899     * @param projectId the ID of the current project
900     * @param resource the resource
901     *
902     * @return the stored content info
903     *
904     * @throws CmsDataAccessException if something goes wrong
905     */
906    default CmsStoredContentInfo readStoredContentInfo(CmsDbContext dbc, CmsUUID projectId, CmsResource resource)
907    throws CmsDataAccessException {
908
909        return new CmsStoredContentInfo(resource, null, null, resource.getLength());
910    }
911
912    /**
913     * Reads the URL name mapping entries which match a given filter.<p>
914     *
915     * @param dbc the database context
916     * @param online if true, reads from the online mapping, else from the offline mapping
917     * @param filter the filter which the entries to be read should match
918     *
919     * @return the mapping entries which match the given filter
920     *
921     * @throws CmsDataAccessException if something goes wrong
922     */
923    List<CmsUrlNameMappingEntry> readUrlNameMappingEntries(
924        CmsDbContext dbc,
925        boolean online,
926        CmsUrlNameMappingFilter filter)
927    throws CmsDataAccessException;
928
929    /**
930     * Reads a resource version numbers.<p>
931     *
932     * @param dbc the current database context
933     * @param projectId the project to read the versions from
934     * @param resourceId the resource id of the resource to read the versions from
935     * @param structureId the structure id of the resource to read the versions from
936     *
937     * @return a map with two entries with keys "structure" and "resource" for the
938     *         structure and resource version number respectively, the values are {@link Integer}
939     *         objects and may be <code>-1</code> if an entry could be found
940     *
941     * @throws CmsDataAccessException if something goes wrong
942     */
943    Map<String, Integer> readVersions(CmsDbContext dbc, CmsUUID projectId, CmsUUID resourceId, CmsUUID structureId)
944    throws CmsDataAccessException;
945
946    /**
947     * Removes a file physically in the database.<p>
948     *
949     * @param dbc the current database context
950     * @param projectId the id of the current project
951     * @param resource the resource
952     *
953     * @throws CmsDataAccessException if something goes wrong
954     */
955    void removeFile(CmsDbContext dbc, CmsUUID projectId, CmsResource resource) throws CmsDataAccessException;
956
957    /**
958     * Removes a folder physically in the database.<p>
959     *
960     * @param dbc the current database context
961     * @param currentProject the current project
962     * @param resource the folder
963     *
964     * @throws CmsDataAccessException if something goes wrong
965     */
966    void removeFolder(CmsDbContext dbc, CmsProject currentProject, CmsResource resource) throws CmsDataAccessException;
967
968    /**
969     * Replaces the content and properties of an existing resource.<p>
970     * @param dbc the current database context
971     * @param newResource the new resource
972     * @param newResourceContent the new content
973     * @param newResourceType the resource type
974     *
975     * @throws CmsDataAccessException if something goes wrong
976     */
977    void replaceResource(CmsDbContext dbc, CmsResource newResource, byte[] newResourceContent, int newResourceType)
978    throws CmsDataAccessException;
979
980    /**
981     * Sets the driver manager for this driver if possible.<p>
982     *
983     * @param driverManager the new driver manager
984     */
985    void setDriverManager(CmsDriverManager driverManager);
986
987    /**
988     * Sets the SQL manager for this driver if possible.<p>
989     *
990     * @param sqlManager the new SQL manager
991     */
992    void setSqlManager(CmsSqlManager sqlManager);
993
994    /**
995     * Transfers the attributes of a resource from to the given users.<p>
996     *
997     * @param dbc the current database context
998     * @param project the current project
999     * @param resource the resource to modify
1000     * @param createdUser the id of the user to be set as the creator of the resource
1001     * @param lastModifiedUser the id of the user to be set as the last modificator of the resource
1002     *
1003     * @throws CmsDataAccessException if something goes wrong
1004     */
1005    void transferResource(
1006        CmsDbContext dbc,
1007        CmsProject project,
1008        CmsResource resource,
1009        CmsUUID createdUser,
1010        CmsUUID lastModifiedUser)
1011    throws CmsDataAccessException;
1012
1013    /**
1014     * Updates the relations on the online project copying the relations from the offline project.<p>
1015     * TODO: add offlineProject parameter
1016     *
1017     * @param dbc the current database context
1018     * @param onlineProject the online project
1019     * @param offlineResource the resource to update the relations for
1020     *
1021     * @throws CmsDataAccessException is something goes wrong
1022     */
1023    void updateRelations(CmsDbContext dbc, CmsProject onlineProject, CmsResource offlineResource)
1024    throws CmsDataAccessException;
1025
1026    /**
1027     * Validates if the specified resource ID in the tables of the specified project {offline|online} exists.<p>
1028     *
1029     * @param dbc the current database context
1030     * @param projectId the project id
1031     * @param resourceId the resource id to test for
1032     *
1033     * @return true if a resource with the given id was found, false otherwise
1034     *
1035     * @throws CmsDataAccessException if something goes wrong
1036     */
1037    boolean validateResourceIdExists(CmsDbContext dbc, CmsUUID projectId, CmsUUID resourceId)
1038    throws CmsDataAccessException;
1039
1040    /**
1041     * Validates if the specified structure ID in the tables of the specified project {offline|online} exists.<p>
1042     *
1043     * @param dbc the current database context
1044     * @param projectId the ID of current project
1045     * @param structureId the structure id
1046     *
1047     * @return true, if the specified structure ID in the tables of the specified project {offline|online} exists
1048     * @throws CmsDataAccessException if something goes wrong
1049     */
1050    boolean validateStructureIdExists(CmsDbContext dbc, CmsUUID projectId, CmsUUID structureId)
1051    throws CmsDataAccessException;
1052
1053    /**
1054     * Writes the resource content for the specified resource.<p>
1055     *
1056     * @param dbc the current database context
1057     * @param resource the resource used to identify the content to update
1058     * @param content the new content of the file
1059     *
1060     * @throws CmsDataAccessException if something goes wrong
1061     */
1062    void writeContent(CmsDbContext dbc, CmsResource resource, byte[] content) throws CmsDataAccessException;
1063
1064    /**
1065     * Writes the "last-modified-in-project" ID of a resource.<p>
1066     *
1067     * @param dbc the current database context
1068     * @param project the resource record is updated with the ID of this project
1069     * @param projectId the project id to write into the resource
1070     * @param resource the resource that gets updated
1071     *
1072     * @throws CmsDataAccessException if something goes wrong
1073     */
1074    void writeLastModifiedProjectId(CmsDbContext dbc, CmsProject project, CmsUUID projectId, CmsResource resource)
1075    throws CmsDataAccessException;
1076
1077    /**
1078     * Writes a property object to the database mapped to a specified resource.<p>
1079     *
1080     * @param dbc the current database context
1081     * @param project the current project
1082     * @param resource the resource where the property should be attached to
1083     * @param property a CmsProperty object containing both the structure and resource value of the property
1084     *
1085     * @throws CmsDataAccessException if something goes wrong
1086     */
1087    void writePropertyObject(CmsDbContext dbc, CmsProject project, CmsResource resource, CmsProperty property)
1088    throws CmsDataAccessException;
1089
1090    /**
1091     * Writes a list of property objects to the database mapped to a specified resource.<p>
1092     *
1093     * @param dbc the current database context
1094     * @param project the current project
1095     * @param resource the resource where the property should be attached to
1096     * @param properties a list of CmsProperty objects
1097     *
1098     * @throws CmsDataAccessException if something goes wrong
1099     */
1100    void writePropertyObjects(CmsDbContext dbc, CmsProject project, CmsResource resource, List<CmsProperty> properties)
1101    throws CmsDataAccessException;
1102
1103    /**
1104     * Writes the structure and/or resource record(s) of an existing file.<p>
1105     *
1106     * Common usages of this method are saving the resource information
1107     * after creating, importing or restoring complete files
1108     * where all file header attributes are changed. Both the structure and resource
1109     * records get written. Thus, using this method affects all siblings of
1110     * a resource! Use {@link #writeResourceState(CmsDbContext, CmsProject, CmsResource, int, boolean)}
1111     * instead if you just want to update the file state, e.g. of a single sibling.<p>
1112     *
1113     * The file state is set to "changed", unless the current state is "new"
1114     * or "deleted". The "changed" argument allows to choose whether the structure
1115     * or resource state, or none of them, is set to "changed".<p>
1116     *
1117     * The rating of the file state values is as follows:<br>
1118     * unchanged &lt; changed &lt; new &lt; deleted<p>
1119     *
1120     * Second, the "state" of the resource is the structure state, if the structure state
1121     * has a higher file state value than the resource state. Otherwise the file state is
1122     * the resource state.<p>
1123     *
1124     * @param dbc the current database context
1125     * @param projectId the id of the current project
1126     * @param resource the resource to be updated
1127     * @param changed determines whether the structure or resource state, or none of them, is set to "changed"
1128     *
1129     * @throws CmsDataAccessException if something goes wrong
1130     *
1131     * @see org.opencms.db.CmsDriverManager#UPDATE_RESOURCE_STATE
1132     * @see org.opencms.db.CmsDriverManager#UPDATE_STRUCTURE_STATE
1133     * @see org.opencms.db.CmsDriverManager#NOTHING_CHANGED
1134     * @see #writeResourceState(CmsDbContext, CmsProject, CmsResource, int, boolean)
1135     */
1136    void writeResource(CmsDbContext dbc, CmsUUID projectId, CmsResource resource, int changed)
1137    throws CmsDataAccessException;
1138
1139    /**
1140     * Writes file state in either the structure or resource record, or both of them.<p>
1141     *
1142     * This method allows to change the resource state to any state by setting the
1143     * desired state value in the specified CmsResource instance.<p>
1144     *
1145     * This method is frequently used while resources are published to set the file state
1146     * back to "unchanged".<p>
1147     *
1148     * Only file state attributes. get updated here. Use {@link #writeResource(CmsDbContext, CmsUUID, CmsResource, int)}
1149     * instead to write the complete file header.<p>
1150     *
1151     * Please refer to the javadoc of {@link #writeResource(CmsDbContext, CmsUUID, CmsResource, int)} to read
1152     * how setting resource state values affects the file state.<p>
1153     *
1154     * @param dbc the current database context
1155     * @param project the current project
1156     * @param resource the resource to be updated
1157     * @param changed determines whether the structure or resource state, or none of them, is set to "changed"
1158     * @param isPublishing if this method is called during publishing to version numbers are updated
1159     *
1160     * @throws CmsDataAccessException if something goes wrong
1161     *
1162     * @see org.opencms.db.CmsDriverManager#UPDATE_RESOURCE_STATE
1163     * @see org.opencms.db.CmsDriverManager#UPDATE_STRUCTURE_STATE
1164     * @see org.opencms.db.CmsDriverManager#UPDATE_ALL
1165     */
1166    void writeResourceState(
1167        CmsDbContext dbc,
1168        CmsProject project,
1169        CmsResource resource,
1170        int changed,
1171        boolean isPublishing)
1172    throws CmsDataAccessException;
1173
1174}